Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions docs/03_reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ corresponds to the `--maxassignlength characters` option of _robot_

## max-error-lines

Type: `int | None`
Type: `int | Literal["NONE"] | None`

Maximum number of error message lines to show in
report when tests fail. Default is 40, minimum is 10
Expand All @@ -1278,6 +1278,10 @@ Examples:
max-error-lines = 40
```

```toml
max-error-lines = "NONE"
```

corresponds to the `--maxerrorlines lines` option of _robot_

## metadata
Expand Down Expand Up @@ -4085,5 +4089,3 @@ xunit = "xunit.xml"
```

corresponds to the `-x --xunit file` option of _robot_


20 changes: 14 additions & 6 deletions docs/public/schemas/robot.toml.json
Original file line number Diff line number Diff line change
Expand Up @@ -4740,16 +4740,20 @@
{
"type": "integer"
},
{
"const": "NONE"
},
{
"type": "null"
}
],
"default": null,
"description": "Maximum number of error message lines to show in\nreport when tests fail. Default is 40, minimum is 10\nand `NONE` can be used to show the full message.\n\nExamples:\n\n```toml\nmax-error-lines = 40\n```\n\ncorresponds to the `--maxerrorlines lines` option of _robot_\n",
"description": "Maximum number of error message lines to show in\nreport when tests fail. Default is 40, minimum is 10\nand `NONE` can be used to show the full message.\n\nExamples:\n\n```toml\nmax-error-lines = 40\n```\n\n```toml\nmax-error-lines = \"NONE\"\n```\n\ncorresponds to the `--maxerrorlines lines` option of _robot_\n",
"examples": [
"max-error-lines = 40"
"max-error-lines = 40",
"max-error-lines = \"NONE\""
],
"markdownDescription": "Maximum number of error message lines to show in\nreport when tests fail. Default is 40, minimum is 10\nand `NONE` can be used to show the full message.\n\nExamples:\n\n```toml\nmax-error-lines = 40\n```\n\ncorresponds to the `--maxerrorlines lines` option of _robot_\n",
"markdownDescription": "Maximum number of error message lines to show in\nreport when tests fail. Default is 40, minimum is 10\nand `NONE` can be used to show the full message.\n\nExamples:\n\n```toml\nmax-error-lines = 40\n```\n\n```toml\nmax-error-lines = \"NONE\"\n```\n\ncorresponds to the `--maxerrorlines lines` option of _robot_\n",
"title": "Max Error Lines",
"x-taplo": {
"links": {
Expand Down Expand Up @@ -7913,16 +7917,20 @@
{
"type": "integer"
},
{
"const": "NONE"
},
{
"type": "null"
}
],
"default": null,
"description": "Maximum number of error message lines to show in\nreport when tests fail. Default is 40, minimum is 10\nand `NONE` can be used to show the full message.\n\nExamples:\n\n```toml\nmax-error-lines = 40\n```\n\ncorresponds to the `--maxerrorlines lines` option of _robot_\n",
"description": "Maximum number of error message lines to show in\nreport when tests fail. Default is 40, minimum is 10\nand `NONE` can be used to show the full message.\n\nExamples:\n\n```toml\nmax-error-lines = 40\n```\n\n```toml\nmax-error-lines = \"NONE\"\n```\n\ncorresponds to the `--maxerrorlines lines` option of _robot_\n",
"examples": [
"max-error-lines = 40"
"max-error-lines = 40",
"max-error-lines = \"NONE\""
],
"markdownDescription": "Maximum number of error message lines to show in\nreport when tests fail. Default is 40, minimum is 10\nand `NONE` can be used to show the full message.\n\nExamples:\n\n```toml\nmax-error-lines = 40\n```\n\ncorresponds to the `--maxerrorlines lines` option of _robot_\n",
"markdownDescription": "Maximum number of error message lines to show in\nreport when tests fail. Default is 40, minimum is 10\nand `NONE` can be used to show the full message.\n\nExamples:\n\n```toml\nmax-error-lines = 40\n```\n\n```toml\nmax-error-lines = \"NONE\"\n```\n\ncorresponds to the `--maxerrorlines lines` option of _robot_\n",
"title": "Max Error Lines",
"x-taplo": {
"links": {
Expand Down
6 changes: 5 additions & 1 deletion packages/robot/src/robotcode/robot/config/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1845,7 +1845,7 @@ class RobotOptions(RobotBaseOptions):
robot_priority=500,
alias="max-assign-length",
)
max_error_lines: Optional[int] = field(
max_error_lines: Optional[Union[int, Literal["NONE"]]] = field(
description="""\
Maximum number of error message lines to show in
report when tests fail. Default is 40, minimum is 10
Expand All @@ -1857,6 +1857,10 @@ class RobotOptions(RobotBaseOptions):
max-error-lines = 40
```

```toml
max-error-lines = "NONE"
```

corresponds to the `--maxerrorlines lines` option of _robot_
""",
robot_name="maxerrorlines",
Expand Down
46 changes: 26 additions & 20 deletions scripts/generate_rf_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
# --- numeric options ---
"--consolewidth": ["console-width = 100"],
"--maxassignlength": ["max-assign-length = 200"],
"--maxerrorlines": ["max-error-lines = 40"],
"--maxerrorlines": ["max-error-lines = 40", 'max-error-lines = "NONE"'],
"--suitestatlevel": ["suite-stat-level = 2"],
# --- single-string options (paths, names, titles, timestamps) ---
"--debugfile": ['debug-file = "debug.log"'],
Expand Down Expand Up @@ -188,21 +188,21 @@ def rewrite_for_extend(snippet: str, base_kebab: str) -> str:
MAX_LINE_LENGTH = 120


def format_field_decl(name: str, type_str: str) -> str:
"""Render a `<name>: <type_str> = field(` line, breaking the type
annotation across lines when the single-line form would exceed
MAX_LINE_LENGTH. Wrapping happens inside the outermost `Optional[...]`
bracket — the same form the existing model.py used by hand.
"""
def format_field_decl(name: str, type_str: str) -> Tuple[str, str, str]:
"""Render a field declaration plus attribute indent and close line."""
one_line = f" {name}: {type_str} = field("
if len(one_line) <= MAX_LINE_LENGTH:
return one_line
return one_line, " ", " )"

wrapped_assign = f" {name}: {type_str} = ("
if len(wrapped_assign) <= MAX_LINE_LENGTH:
return f"{wrapped_assign}\n field(", " ", " )\n )"

if type_str.startswith("Optional[") and type_str.endswith("]"):
inner = type_str[len("Optional[") : -1]
return f" {name}: Optional[\n {inner}\n ] = field("
# No structural break point we know how to handle — leave it long and
# let ruff format decide.
return one_line
return f" {name}: Optional[\n {inner}\n ] = field(", " ", " )"

return f"{wrapped_assign}\n field(", " ", " )\n )"


def apply_toml_examples(desc: str, long: str, base_kebab: str, extend: bool) -> str:
Expand All @@ -219,6 +219,7 @@ def apply_toml_examples(desc: str, long: str, base_kebab: str, extend: bool) ->
type_templates = {
"console": 'Literal["verbose", "dotted", "skipped", "quiet", "none"]',
"listeners": "Dict[str, List[Union[str, StringExpression]]]",
"max_error_lines": 'Union[int, Literal["NONE"]]',
"parsers": "Dict[str, List[Union[str, StringExpression]]]",
"pre_rebot_modifiers": "Dict[str, List[Union[str, StringExpression]]]",
"pre_run_modifiers": "Dict[str, List[Union[str, StringExpression]]]",
Expand Down Expand Up @@ -407,20 +408,24 @@ def build_class_fields(output: List[str], opts: Dict[str, Any], extend: bool = F
name = ("extend_" if extend else "") + base_name
base_kebab = base_name.replace("_", "-")
type_str = get_type(name, internal_options[long_name]["default"], v, is_flag, extend)
field_decl = format_field_decl(name, type_str)
field_decl, field_indent, field_close = format_field_decl(name, type_str)
output.append(
f'{field_decl}\n description="""\\\n{create_desc(v, extend, base_kebab)}\n """,'
f'{field_decl}\n{field_indent}description="""\\\n'
f'{create_desc(v, extend, base_kebab)}\n """,'
)
if not extend:
output.append(f' robot_name="{long_name}",')
output.append(" robot_priority=500,")
output.append(f'{field_indent}robot_name="{long_name}",')
output.append(f"{field_indent}robot_priority=500,")
if v["short"] is not None:
output.append(f' robot_short_name="{v["short"][1:]}",')
output.append(f'{field_indent}robot_short_name="{v["short"][1:]}",')
if is_flag:
output.append(" robot_is_flag=True,")
output.append(f"{field_indent}robot_is_flag=True,")
if not flag_default:
output.append(f" robot_flag_default={flag_default},")
output.append(" )")
output.append(f"{field_indent}robot_flag_default={flag_default},")
alias = ("extend-" if extend else "") + base_kebab
if alias != name:
output.append(f'{field_indent}alias="{alias}",')
output.append(field_close)

return result

Expand Down Expand Up @@ -547,6 +552,7 @@ def build_class_fields(output: List[str], opts: Dict[str, Any], extend: bool = F
extra=True,
tool="testdoc",
)
output.extend(["", ""])

model_file = Path("packages/robot/src/robotcode/robot/config/model.py")
original_lines = model_file.read_text().splitlines()
Expand Down
38 changes: 38 additions & 0 deletions tests/robotcode/robot/config/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,44 @@ def test_profiles_flatten_keywords_supports_literals_and_patterns() -> None:
]


@pytest.mark.parametrize(
("value", "expected"),
[
("10", "10"),
("40", "40"),
('"NONE"', "NONE"),
],
)
def test_max_error_lines_builds_command_line(value: str, expected: str) -> None:
data = f"""\
max-error-lines = {value}
"""
config = load_robot_config_from_robot_toml_str(data)
cmd_line = config.combine_profiles().evaluated().build_command_line()
assert config.max_error_lines == (int(expected) if expected.isdigit() else expected)
assert cmd_line == ["--maxerrorlines", expected]


@pytest.mark.parametrize(
("value", "expected"),
[
("10", "10"),
("40", "40"),
('"NONE"', "NONE"),
],
)
def test_profile_max_error_lines_builds_command_line(value: str, expected: str) -> None:
data = f"""\
[profiles.full-errors]
max-error-lines = {value}
"""
config = load_robot_config_from_robot_toml_str(data)
profile = config.combine_profiles("full-errors")
cmd_line = config.combine_profiles("full-errors").evaluated().build_command_line()
assert profile.max_error_lines == (int(expected) if expected.isdigit() else expected)
assert cmd_line == ["--maxerrorlines", expected]


def test_set_and_evaluates_environment_var_correctly() -> None:
os.environ.pop("ENV_TEST_VAR", None)
os.environ.pop("ENV_TEST_VAR_CALCULATED", None)
Expand Down