def test_results_are_correctly_serialized(): """ Test that DangerResults model is correctly serialized. """ results = DangerResults( fails=[Violation(message="Fail")], warnings=[ Violation(message="Warning", file_name="warning.py", line=99) ], messages=[Violation(message="Message")], markdowns=[Violation(message="Markdown")], ) json = serialize_results(results) assert json == { "fails": [{ "message": "Fail" }], "warnings": [{ "message": "Warning", "file": "warning.py", "line": 99 }], "messages": [{ "message": "Message" }], "markdowns": [{ "message": "Markdown" }], "meta": { "runtimeName": "danger-python", "runtimeHref": "https://danger.systems/python", }, }
def test_that_plugin_method_has_access_to_danger_and_reporting_methods( danger: Danger): """ Test that plugin method has access to the danger DSL and also the methods for providing messages, markdowns, warnings and fails. """ tests.print_modified_files() # type: ignore assert danger.results == DangerResults( fails=[ Violation(message="Files modified: 4", file_name="fail.py", line=3) ], warnings=[ Violation(message="Files modified: 4", file_name="warn.py", line=2) ], markdowns=[ Violation(message="Files modified: 4", file_name="markdown.py", line=1) ], messages=[ Violation(message="Files modified: 4", file_name="message.py", line=0) ], )
def test_violations_in_touched_files(): output = ( "./danger_flake8/plugin.py:7:1: F401 'profile' imported but unused\n" "./danger_flake8/plugin.py:18:1: W391 blank line at end of file\n" "./tests/test_violation.py:5:1: F401 'profile' imported but unused\n" "./tests/test_violation.py:7:1: E302 expected 2 blank lines, found 1\n" "./tests/test_violation.py:42:1: W391 blank line at end of file\n" "./danger_flake8/violation.py:21:1: W391 blank line at end of file\n") touched_files = {"danger_flake8/plugin.py", "danger_flake8/violation.py"} violations_list = violations(output, touched_files) assert violations_list == [ Violation( message="F401 'profile' imported but unused", file_name="danger_flake8/plugin.py", line=7, ), Violation( message="W391 blank line at end of file", file_name="danger_flake8/plugin.py", line=18, ), Violation( message="W391 blank line at end of file", file_name="danger_flake8/violation.py", line=21, ), ]
def test_message_method_appends_message_to_results(): """ Test that message method appends a message to results. """ message("Hey, this is great!") message("This file is too big", "big_file.py", 2049) assert len(Danger.results.messages) == 2 assert Danger.results.messages[0] == Violation( message="Hey, this is great!") assert Danger.results.messages[1] == Violation( message="This file is too big", file_name="big_file.py", line=2049)
def test_markdown_method_appends_markdown_to_results(): """ Test that markdown method appends a message to results. """ markdown("Markdown #1") markdown("Markdown #2", "README.md", 1) assert len(Danger.results.markdowns) == 2 assert Danger.results.markdowns[0] == Violation(message="Markdown #1") assert Danger.results.markdowns[1] == Violation(message="Markdown #2", file_name="README.md", line=1)
def test_fail_method_appends_failure_to_results(): """ Test that fail method appends a failure to results. """ fail("Division by zero") fail("This crashes due to invalid shoe size", "shoes.py", 99) assert len(Danger.results.fails) == 2 assert Danger.results.fails[0] == Violation(message="Division by zero") assert Danger.results.fails[1] == Violation( message="This crashes due to invalid shoe size", file_name="shoes.py", line=99)
def test_warn_method_appends_warning_to_results(): """ Test that warn method appends a warning to results. """ warn("Possible memory leak") warn("This method is deprecated", "deprecated.py", 29) assert len(Danger.results.warnings) == 2 assert Danger.results.warnings[0] == Violation( message="Possible memory leak") assert Danger.results.warnings[1] == Violation( message="This method is deprecated", file_name="deprecated.py", line=29)
def violation(text_violation: str) -> Optional[Violation]: if not text_violation: return None message = text_violation.split(":")[3][1:] file_name = text_violation.split(":")[0][2:] line = text_violation.split(":")[1] return Violation(message=message, file_name=file_name, line=line)
def test_plugin_does_fail_when_jscpd_not_installed(danger: Danger): with patch("subprocess.Popen", new_callable=MockPopen) as popen: popen.set_command("which jscpd", returncode=1) plugin = DangerJSCPD() plugin.jscpd() message = "Could not find jscpd in current directory, please run command `npm install -g jscpd`" assert danger.results.fails == [Violation(message=message)]
def test_violation_is_correctly_serialized_with_optional_types(): """ Test that Violation model is correctly serialized with optional types. """ violation = Violation(message="Message") json = serialize_violation(violation) assert json == {"message": "Message"}
def test_violation_is_correctly_serialized(): """ Test that Violation model is correctly serialized. """ violation = Violation(message="Title", file_name="file.py", line=28) json = serialize_violation(violation) assert json == {"message": "Title", "file": "file.py", "line": 28}
def test_lint_touched_files(danger: Danger): with open("tests/fixtures/flake8_output") as fixture: with patch("subprocess.Popen", new_callable=MockPopen) as popen: popen.set_command("flake8", stdout=fixture.read().encode("utf-8")) plugin = DangerFlake8() plugin.lint() assert danger.results.warnings == [ Violation( message="W391 blank line at end of file", file_name="danger_flake8/violation.py", line=21, ), Violation( message="F401 'profile' imported but unused", file_name="tests/test_violation.py", line=5, ), ]
def test_plugin_could_not_find_jscpd_report(danger: Danger): with patch("subprocess.Popen", new_callable=MockPopen) as popen: popen.set_command("which jscpd", returncode=0) popen.set_command("jscpd . -r json", returncode=0) with Patcher(): plugin = DangerJSCPD() plugin.jscpd() message = "Could not find jscpd-report.json in report directory" assert danger.results.fails == [Violation(message=message)]
def test_plugin_does_fail_the_build_if_minimum_coverage_is_not_met(danger: Danger): """ Test plugin fails the build if minimum coverage is not met. """ plugin = DangerCoverage() plugin.report_coverage( report_path="tests/fixtures/cov_fixture.xml", sources_path="danger_py_cov_example/", minimum_coverage=66.70, ) expected_message = ( "### Current coverage is `66.67%`\n" "No source changes affecting the coverage found\n" ) expected_fail = "Minimum required coverage `66.70%` not met" assert danger.results.markdowns == [Violation(message=expected_message)] assert danger.results.fails == [Violation(message=expected_fail)]
def test_lint_modified_files(danger: Danger): with open("tests/fixtures/flake8_output") as fixture: with patch("subprocess.Popen", new_callable=MockPopen) as popen: popen.set_command("flake8", stdout=fixture.read().encode("utf-8")) plugin = DangerFlake8() plugin.lint() assert danger.results.warnings == [ Violation( message="F811 redefinition of unused 'DangerPlugin' from line 1", file_name="danger_flake8/plugin.py", line=2, ), Violation( message="E303 too many blank lines (3)", file_name="danger_flake8/plugin.py", line=6, ), Violation( message="W391 blank line at end of file", file_name="danger_flake8/plugin.py", line=11, ), ]
def test_plugin_does_not_print_table_if_there_are_no_changed_files(danger: Danger): """ Test plugin does not print coverage table if there are no changed and/or created files. """ plugin = DangerCoverage() plugin.report_coverage( report_path="tests/fixtures/cov_fixture.xml", sources_path="danger_py_cov_example/", ) expected_message = ( "### Current coverage is `66.67%`\n" "No source changes affecting the coverage found\n" ) assert danger.results.markdowns == [Violation(message=expected_message)] assert danger.results.fails == []
def test_plugin_allows_to_customize_paths(danger: Danger): with patch("subprocess.Popen", new_callable=MockPopen) as popen: popen.set_command("which jscpd", returncode=0) popen.set_command("jscpd tests hello_world -r json", returncode=0) with open("tests/fixtures/jscpd-report.json") as report: with Patcher() as patcher: patcher.fs.create_file("report/jscpd-report.json", contents=report.read()) plugin = DangerJSCPD() plugin.jscpd(paths=["tests", "hello_world"]) expected_markdown = ( "### JSCPD found 1 clone(s)\n" "| First | Second |\n" "| ----- | ------ |\n" "| tests/test_model_pickling.py: 87-95 | tests/test_model_pickling.py: 61-71 |" ) assert danger.results.markdowns == [Violation(message=expected_markdown)]
def test_plugin_that_generate_warn_and_markdown_with_valid_jscpd_report(danger: Danger): with patch("subprocess.Popen", new_callable=MockPopen) as popen: popen.set_command("which jscpd", returncode=0) popen.set_command("jscpd . -r json", returncode=0) with open("tests/fixtures/jscpd-report.json") as report: with Patcher() as patcher: patcher.fs.create_file("report/jscpd-report.json", contents=report.read()) plugin = DangerJSCPD() plugin.jscpd() expected_markdown = ( "### JSCPD found 3 clone(s)\n" "| First | Second |\n" "| ----- | ------ |\n" "| examples/babi_rnn.py: 91-123 | examples/babi_memnn.py: 46-79 |\n" "| examples/babi_rnn.py: 124-131 | examples/babi_memnn.py: 80-87 |\n" "| examples/cifar10_resnet.py: 344-355 | examples/cifar10_resnet.py: 248-259 |" ) assert danger.results.markdowns == [Violation(message=expected_markdown)]
def test_plugin_appends_coverage_results_to_markdown(danger: Danger): """ Test plugin appends coverage results to markdown. """ plugin = DangerCoverage() plugin.report_coverage( report_path="tests/fixtures/cov_fixture.xml", sources_path="danger_py_cov_example/", ) expected_message = ( "### Current coverage is `66.67%`\n" "| Files changed | Coverage | - |\n" "| ------------- | -------- | --- |\n" "| module_one.py | `71.43%` | :warning: |\n" "| module_three.py | `100.00%` | :white_check_mark: |\n" "| module_two.py | `0.00%` | :skull: |\n" ) assert danger.results.markdowns == [Violation(message=expected_message)] assert danger.results.fails == []