Check Tags

htmlwhat.check contain all the check related functions. check_ functions are responsible for verifying the presence of HTML tags in a given code.

check_doctype(state, missing_msg='Are you sure you defined `<{{tag}}>`?', expand_msg='Did you correctly specify the `<{{tag}}>`?', append=False, **kwargs)

Check whether the student code contain the <!DOCTYPE> tag at the first line or not.

It compares the first element or tag of the solution and student AST (Abstract Syntax Tree) of state to determine if the <!DOCTYPE> tag is present.

Parameters:
  • state (object) – State instance describing student and solution code. Can be omitted if used with Ex().

  • missing_msg (str, optional) – Message to display if <!DOCTYPE> tag is missing in student code.

  • expand_msg (str, optional) – If specified, this overrides any messages that are prepended by previous SCT chains.

  • append (bool, optional) – Whether to append the message into the message chain. Only work if this test failed, it does not break the chain if future test fails. Basically, only the message of this function will be provided on fail.

  • kwargs – By default missing_msg and expand_msg uses jinja template so you can provide additional information using kwargs to add in feedback. default tag="!DOCTYPE" is not modifiable.

Returns:

The child State object with appropriate messages and ASTs.

Return type:

State

Raises:
  • InstructorError – If <!DOCTYPE> tag is not found in solution code.

  • TestFail – If <!DOCTYPE> tag is not found in student code. (aka feedback)

Example:
>>> from htmlwhat.State import State
>>> from htmlwhat.checks import check_doctype
>>> student_code = """ """
>>> solution_code = """
... <!DOCTYPE html>
... <html>
...    <head>
...    </head>
...    <body>
...    </body>
... </html>
... """
>>> state = State(student_code=student_code, solution_code=solution_code)
>>> check_doctype(state)
Traceback (most recent call last): ...
protowhat.failure.TestFail: Are you sure you defined `<!DOCTYPE>`?

Note

  • If you are not familiar with what Ex() is at the moment, don’t worry. It will be explained in the How to Write Tests section.

check_html(state, missing_msg='Are you sure you included `<{{tag}}>` tag?', expand_msg='Inspect the `<{{tag}}>` tag', append=False, **kwargs)

Check whether the student code contain the <html> tag or not.

Parameters:
  • state (object) – State instance describing student and solution code. Can be omitted if used with Ex().

  • missing_msg (str, optional) – Message to display if <html> tag is missing in student code.

  • expand_msg (str, optional) – If specified, this overrides any messages that are prepended by previous SCT chains.

  • append (bool, optional) – Whether to append the message into the message chain. Only work if this test failed, it does not break the chain if future test fails. Basically, only the feedback of this function will be provided on fail.

  • kwargs – Additional keyword arguments to pass into missing_msg or expand_msg jinja template.

Returns:

The child State object with appropriate messages and ASTs.

Return type:

State

Raises:
  • InstructorError – If <html> tag is not found in solution code.

  • TestFail – If <html> tag is not found in student code. (aka feedback)

Example:
>>> from htmlwhat.State import State
>>> from htmlwhat.checks import check_html
>>> student_code = """ """
>>> solution_code = """
... <!DOCTYPE html>
... <html>
...    <head>
...    </head>
...    <body>
...    </body>
... </html>
... """
>>> state = State(student_code=student_code, solution_code=solution_code)
>>> check_html(state)
Traceback (most recent call last): ...
protowhat.failure.TestFail: Are you sure you included `<html>` tag?
check_head(state, missing_msg='Are you sure you included `<{{tag}}>` tag?', expand_msg='Inspect the `<{{tag}}>` tag', append=False, **kwargs)

Check whether the student code contains the <head> tag or not.

Parameters:
  • state (object) – State instance describing student and solution code. Can be omitted if used with Ex().

  • missing_msg (str, optional) – Message to display if <head> tag is missing in student code.

  • expand_msg (str, optional) – If specified, this overrides any messages that are prepended by previous SCT chains.

  • append (bool, optional) – Whether to append the message into the message chain. Only work if this test failed, it does not break the chain if future test fails. Basically, only the feedback of this function will be provided on fail.

  • kwargs – Additional keyword arguments to pass into missing_msg or expand_msg jinja template.

Returns:

The child State object with appropriate messages and ASTs.

Return type:

State

Raises:
  • InstructorError – If <head> tag is not found in solution code.

  • TestFail – If <head> tag is not found in student code.

Example:
>>> from htmlwhat.State import State
>>> from htmlwhat.checks import check_head
>>> student_code = """"""
>>> solution_code = """
... <!DOCTYPE html>
... <html>
...    <head>
...    </head>
...    <body>
...    </body>
... </html>
... """
>>> state = State(student_code=student_code, solution_code=solution_code)
>>> check_head(state)
Traceback (most recent call last): ...
protowhat.failure.TestFail: Are you sure you included `<head>` tag?
check_body(state, missing_msg='Are you sure you included `<{{tag}}>` tag?', expand_msg='Inspect the `<{{tag}}>` tag', append=False, **kwargs)

Check whether the student code contains the <body> tag or not.

Parameters:
  • state (object) – State instance describing student and solution code. Can be omitted if used with Ex().

  • missing_msg (str, optional) – Message to display if <body> tag is missing in student code.

  • expand_msg (str, optional) – If specified, this overrides any messages that are prepended by previous SCT chains.

  • append (bool, optional) – Whether to append the message into the message chain. Only work if this test failed, it does not break the chain if future test fails. Basically, only the feedback of this function will be provided on fail.

  • kwargs – Additional keyword arguments to pass into missing_msg or expand_msg jinja template.

Returns:

The child State object with appropriate messages and ASTs.

Return type:

State

Raises:
  • InstructorError – If <body> tag is not found in solution code.

  • TestFail – If <body> tag is not found in student code.

Example:
>>> from htmlwhat.State import State
>>> from htmlwhat.checks import check_body
>>> student_code = """"""
>>> solution_code = """
... <!DOCTYPE html>
... <html>
...    <head>
...    </head>
...    <body>
...    </body>
... </html>
... """
>>> state = State(student_code=student_code, solution_code=solution_code)
>>> check_body(state)
Traceback (most recent call last): ...
protowhat.failure.TestFail: Are you sure you included `<body>` tag?
check_tag(state, name: str, index=0, missing_msg='Did you include the {{index}}`{{tag}}` tag properly?', expand_msg='Check the {{index}}`{{tag}}` tag', append=True, **kwargs)

Check the presence of a specific tag in the student code. This is a generic function that can be used to check for any tag, it will only check the direct children of the current state or tag.

<body>
    <div> <!-- 1st -->
        <div> <!-- 2st -->
        </div>
    </div>
    <div> <!-- 3rd -->
    </div>
</body>

In the code above div 1st and 3rd are direct children of body tag, and div 2nd is a direct child of div 1st.

Parameters:
  • state (object) – State instance describing student and solution code. Can be omitted if used with Ex().

  • name (str) – The name of the tag to check for. If you want to check for <span> tag then pass "span".

  • index (int, optional) – The index of the tag to check for. If there are multiple tags with the same name, you can specify the index (0-based indexing) to check for. Default is 0.

  • missing_msg (str, optional) – Message to display if given tag is missing in student code.

  • expand_msg (str, optional) – If specified, this overrides any messages that are prepended by previous SCT chains.

  • append (bool, optional) – Whether to append the message into the message chain. Only work if this test failed, it does not break the chain if future test fails. Basically, only the feedback of this function will be provided on fail.

  • kwargs – Additional keyword arguments to pass into missing_msg or expand_msg jinja template.

Returns:

The child State object with appropriate messages and ASTs.

Return type:

State

Raises:
  • InstructorError – If the given tag is not found in solution code.

  • TestFail – If the given tag is not found in student code.

Example:
>>> from htmlwhat.State import State
>>> from htmlwhat.checks import check_tag, check_body, check_html
>>> student_code = """
... <!DOCTYPE html>
... <html>
...    <body>
...    </body>
... </html>
... """
>>> solution_code = """
... <!DOCTYPE html>
... <html>
...    <head>
...    </head>
...    <body>
...        <div>
...        </div>
...    </body>
... </html>
... """
>>> state = State(student_code=student_code, solution_code=solution_code)
>>> html_state = check_html(state)  # 1st test
>>> body_state = check_body(html_state)  # 2nd test
>>> check_tag(body_state, "div")  # 3rd test
Traceback (most recent call last): ...
protowhat.failure.TestFail: Inspect the `<body>` tag with in `html`. Did you include the `div` tag properly?

Check Tag Values

Now we know how to check a tag present in the code. But what if we want to check the values or attributes of a tag? has_ functions are responsible for verifying the presence of different kind of values in a given tag. This functions always return the state that they were intially passed and are recommended to use at the ‘end’ of a chain.

has_equal_attr(state, attrs: Optional[Union[List[str], Tuple[str]]] = None, missing_msg: str = 'Expected attribute `{{attr}}` not found.', incorrect_msg: str = 'Expected attribute `{{attr}}` to be `"{{sol}}"`, but found `"{{stu}}"`.', check_values: bool = True, append: bool = True, **kwargs)

Check whether the student code have the same attributes as the solution code.

This function first checks for the presence of attributes in the student code, and if found then compares their values with the solution code.

Parameters:
  • state (object) – State instance describing student and solution code. Can be omitted if used with Ex().

  • attrs (List[str] | Tuple[str] | None, optional) – The list or tuple of attributes of the solution to check. If None, all attributes in the solution code will be checked.

  • missing_msg (str, optional) – Message to display if any attribute is missing in student code.

  • incorrect_msg (str, optional) – Message to display if any attribute with the incorret value is found.

  • check_values (bool, optional) – Whether to check the attribute values for equality. If False, only the presence of attributes will be checked.

  • append (bool, optional) – Whether to append the message to the existing report. If False, only the message of this function will display.

  • kwargs – Additional keyword arguments to pass into missing_msg or incorrect_msg jinja template.

Returns:

The same State object with updatted messages. And hence recommended to use at the end of the chain.

Return type:

State

Raises:
  • InstructorError – If an attribute specified in attrs is missing in the solution code.

  • TestFail – If an attribute specified in attrs is missing in the student code or has an incorrect value. (aka feedback)

Example:
>>> from htmlwhat.State import State
>>> from htmlwhat.checks import check_body, has_equal_attr
>>> student_code = """
... <!DOCTYPE html>
...    <html>
...        <head>
...        </head>
...        <body>
...        </body>
...    </html> 
... """
>>> solution_code = """
... <!DOCTYPE html>
...    <html>
...        <head>
...        </head>
...        <body width="40px" class="example" >
...        </body>
...    </html> 
... """
>>> state = State(student_code=student_code, solution_code=solution_code)
>>> body_state = check_body(state)
>>> has_equal_attr(body_state)
Traceback (most recent call last): ...
protowhat.failure.TestFail: Inspect the `<body>` tag. Expected attribute `width` not found.

Let’s modify student_code-

>>> student_code = """
... <!DOCTYPE html>
...    <html>
...        <head>
...        </head>
...        <body width="40px" class="hello">
...        </body>
...    </html> 
... """

And run the code again,

Inspect the `<body>` tag. Expected attribute `class` to be `"example"`, but found `"hello"`.
has_equal_text(state, incorrect_msg: str = 'Expected text not found.', show_text: bool = False, append: bool = True, **kwargs)

Check whether the student and solution code have identical text. Keep in mind that this function get text of child tags as well.

Hence in the code <body>Hello<p>this is paragraph</p>World</body>, text of body is “Hello this is paragraph World” and not only “Hello World”.

Parameters:
  • state (object) – State instance describing student and solution code. Can be omitted if used with Ex().

  • incorrect_msg (str, optional) – The message to display if student text not equal to solution text.

  • show_text (bool, optional) – Whether to include the actual text in the error message. Default is False.

  • append (bool, optional) – Whether to append the message to the existing report. If False, only the message of this function will display.

  • kwargs – Additional keyword arguments to pass into missing_msg or expand_msg jinja template.

Returns:

The same State object with updatted messages. And hence recommended to use at the end of the chain.

Return type:

State

Raises:

TestFail – If the student text is not strictly equal to the solution text. (aka feedback)

Example:
>>> from htmlwhat.State import State
>>> from htmlwhat.checks import check_head, check_tag, has_equal_text
>>> student_code = """
... <!DOCTYPE html>
...    <html>
...        <head>
...        <title>412-52-2524</title>
...        </head>
...    </html> 
... """
>>> solution_code = """
... <!DOCTYPE html>
...    <html>
...        <head>
...        <title>412-52-2222</title>
...        </head>
...    </html> 
... """
>>> state = State(student_code=student_code, solution_code=solution_code)
>>> head_state = check_head(state)
>>> title_state = check_tag(head_state, "title")
>>> has_equal_text(title_state, show_text=True)
Traceback (most recent call last): ...
protowhat.failure.TestFail: Check the `title` tag with in `head`. Expected text `412-52-2222` but found `412-52-2524`
has_code(state, text: str, incorrect_msg: str = "Didn't find {{text}} in your code.", fixed: bool = True, append=True, **kwargs)

Check whether the student code contains a specific text or follows a regex pattern. This function is a primary designed for regex pattern matching and is solution and AST independent, hence not required solution to contain the text.

Parameters:
  • state (object) – State instance describing student and solution code. Can be omitted if used with Ex().

  • text (str) – The text or regex pattern to search for in the student code.

  • incorrect_msg (str, optional) – The message to display if the text or pattern is not found in student code.

  • fixed (bool, optional) – Fixed should be False for regex text. Default is True, for checking fixed text present in the student code.

  • append (bool, optional) – Whether to append the message to the existing report. If False, only the message of this function will display.

  • kwargs – Additional keyword arguments to pass into missing_msg or expand_msg jinja template.

Returns:

The same State object with updatted messages. And hence recommended to use at the end of the chain.

Return type:

State

Raises:

TestFail – If the given text is not found in student code. (aka feedback)

Example:
>>> from htmlwhat.State import State
>>> from htmlwhat.checks import has_code
>>> student_code = """
... <!DOCTYPE html>
... <html>
...    <head>
...        <title>12-52-2524</title>
...    </head>
... </html>
... """
>>> solution_code = """ """
>>> state = State(student_code=student_code, solution_code=solution_code)
>>> has_code(state, text=".*\d{3}-\d{2}-\d{4}.*", fixed=False)
Traceback (most recent call last): ...
protowhat.failure.TestFail: Didn't find the pattern `.*\d{3}-\d{2}-\d{4}.*` in your code.