From: Jean Privat Date: Sun, 5 Jun 2016 16:12:49 +0000 (-0400) Subject: Merge: nitls: fix tree representation of nested groups X-Git-Url: http://nitlanguage.org?hp=47c7a9ffff87129f74b814bd11ffd84050d699af Merge: nitls: fix tree representation of nested groups nitls wrongly detached some nested groups in tree-mode. Before: ~~~ $ nitls -tp lib/nitcorn/examples/src/nitcorn_hello_world.nit lib/nitcorn/http_response.nit lib/nitcorn/examples `--lib/nitcorn/examples/src `--lib/nitcorn/examples/src/nitcorn_hello_world.nit lib/nitcorn `--lib/nitcorn/http_response.nit ~~~ After: ~~~ $ nitls -tp lib/nitcorn/examples/src/nitcorn_hello_world.nit lib/nitcorn/http_response.nit lib/nitcorn |--lib/nitcorn/examples | `--lib/nitcorn/examples/src | `--lib/nitcorn/examples/src/nitcorn_hello_world.nit `--lib/nitcorn/http_response.nit ~~~ Pull-Request: #2161 Reviewed-by: Alexis Laferrière --- diff --git a/contrib/pep8analysis/package.ini b/contrib/pep8analysis/package.ini index 43d5e4a..bbf3802 100644 --- a/contrib/pep8analysis/package.ini +++ b/contrib/pep8analysis/package.ini @@ -3,6 +3,8 @@ name=pep8analysis tags=educ,web,cli maintainer=Alexis Laferrière license=Apache-2.0 +[source] +exclude=src/parser/parser_abs.nit [upstream] browse=https://github.com/nitlang/nit/tree/master/contrib/pep8analysis/ git=https://github.com/nitlang/nit.git diff --git a/share/man/nitunit.md b/share/man/nitunit.md index 6f09402..23b7382 100644 --- a/share/man/nitunit.md +++ b/share/man/nitunit.md @@ -173,7 +173,23 @@ end Sometimes, it is easier to validate a `TestCase` by comparing its output with a text file containing the expected result. -For each TestCase `test_bar` of a TestSuite `test_mod.nit`, if the corresponding file `test_mod.sav/test_bar.res` exists, then the output of the test is compared with the file. +For each TestCase `test_bar` of a TestSuite `test_mod.nit`, a corresponding file with the expected output is looked for: + +* "test_mod.sav/test_bar.res". I.e. test-cases grouped by test-suites. + + This is the default and is useful if there is a lot of test-suites and test-cases in a directory + +* "sav/test_bar.res". I.e. all test-cases grouped in a common sub-directory. + + Useful if there is a lot of test-suites OR test-cases in a directory. + +* "test_bar.res" raw in the directory. + + Useful is there is a few test-suites and test-cases in a directory. + +All 3 are exclusive. If more than one exists, the test-case is failed. + +If a corresponding file then the output of the test-case is compared with the file. The `diff(1)` command is used to perform the comparison. The test is failed if non-zero is returned by `diff`. @@ -195,6 +211,9 @@ Hello! If no corresponding `.res` file exists, then the output of the TestCase is ignored. +To helps the management of the expected results, the option `--autosav` can be used to automatically create and update them. + + ## Configuring TestSuites `TestSuites` also provide methods to configure the test run: @@ -292,6 +311,16 @@ Examples: `TestFoo`, `TestFoo*`, `TestFoo::test_foo`, `TestFoo::test_foo*`, `tes ### `-t`, `--target-file` Specify test suite location. +### `--autosav` +Automatically create/update .res files for black box testing. + +If a black block test fails because a difference between the expected result and the current result then the expected result file is updated (and the test is passed). + +If a test-case of a test-suite passes but that some output is generated, then an expected result file is created. + +It is expected that the created/updated files are checked since the tests are considered passed. +A VCS like `git` is often a good tool to check the creation and modification of those files. + ## SUITE GENERATION ### `--gen-suite` diff --git a/src/loader.nit b/src/loader.nit index 967d335..d1a4ce5 100644 --- a/src/loader.nit +++ b/src/loader.nit @@ -379,6 +379,13 @@ redef class ModelBuilder var mgrouppath = path.join_path("..").simplify_path var mgroup = identify_group(mgrouppath) + if mgroup != null then + var mpackage = mgroup.mpackage + if not mpackage.accept(path) then + mgroup = null + toolcontext.info("module `{path}` excluded from package `{mpackage}`", 2) + end + end if mgroup == null then # singleton package var loc = new Location.opaque_file(path) @@ -473,6 +480,13 @@ redef class ModelBuilder if not stopper.file_exists then # Recursively get the parent group parent = identify_group(parentpath) + if parent != null then do + var mpackage = parent.mpackage + if not mpackage.accept(dirpath) then + toolcontext.info("directory `{dirpath}` excluded from package `{mpackage}`", 2) + parent = null + end + end if parent == null then # Parent is not a group, thus we are not a group either mgroups[rdp] = null @@ -1064,6 +1078,27 @@ redef class MPackage # # Some packages, like stand-alone packages or virtual packages have no `ini` file associated. var ini: nullable ConfigTree = null + + # Array of relative source paths excluded according to the `source.exclude` key of the `ini` + var excludes: nullable Array[String] is lazy do + var ini = self.ini + if ini == null then return null + var exclude = ini["source.exclude"] + if exclude == null then return null + var excludes = exclude.split(":") + return excludes + end + + # Does the source inclusion/inclusion rules of the package `ini` accept such path? + fun accept(filepath: String): Bool + do + var excludes = self.excludes + if excludes != null then + var relpath = root.filepath.relpath(filepath) + if excludes.has(relpath) then return false + end + return true + end end redef class MGroup diff --git a/src/modelbuilder_base.nit b/src/modelbuilder_base.nit index 85bb115..5cc235f 100644 --- a/src/modelbuilder_base.nit +++ b/src/modelbuilder_base.nit @@ -348,6 +348,12 @@ class ModelBuilder var name = qid.n_id.text var qname = qid.full_name + if bad_class_names[mmodule].has(qname) then + error(qid, "Error: class `{qname}` not found in module `{mmodule}`.") + return + end + bad_class_names[mmodule].add(qname) + var all_classes = model.get_mclasses_by_name(name) var hints = new Array[String] @@ -404,6 +410,10 @@ class ModelBuilder error(qid, "Error: class `{qname}` not found in module `{mmodule}`.") end + # List of already reported bad class names. + # Used to not perform and repeat hints again and again. + private var bad_class_names = new MultiHashMap[MModule, String] + # Return the static type associated to the node `ntype`. # `mmodule` and `mclassdef` is the context where the call is made (used to understand formal types) # In case of problem, an error is displayed on `ntype` and null is returned. diff --git a/src/nitunit.nit b/src/nitunit.nit index 8d79e80..c9aa8ae 100644 --- a/src/nitunit.nit +++ b/src/nitunit.nit @@ -20,7 +20,7 @@ import testing var toolcontext = new ToolContext -toolcontext.option_context.add_option(toolcontext.opt_full, toolcontext.opt_output, toolcontext.opt_dir, toolcontext.opt_noact, toolcontext.opt_pattern, toolcontext.opt_file, toolcontext.opt_gen_unit, toolcontext.opt_gen_force, toolcontext.opt_gen_private, toolcontext.opt_gen_show, toolcontext.opt_nitc) +toolcontext.option_context.add_option(toolcontext.opt_full, toolcontext.opt_output, toolcontext.opt_dir, toolcontext.opt_noact, toolcontext.opt_pattern, toolcontext.opt_file, toolcontext.opt_autosav, toolcontext.opt_gen_unit, toolcontext.opt_gen_force, toolcontext.opt_gen_private, toolcontext.opt_gen_show, toolcontext.opt_nitc) toolcontext.tooldescription = "Usage: nitunit [OPTION]... ...\nExecutes the unit tests from Nit source files." toolcontext.process_options(args) diff --git a/src/package.ini b/src/package.ini index 292ff28..c7dae85 100644 --- a/src/package.ini +++ b/src/package.ini @@ -3,6 +3,8 @@ name=nitc tags=devel,cli maintainer=Jean Privat license=Apache-2.0 +[source] +exclude=parser/parser_abs.nit:parser/.parser-nofact.nit [upstream] browse=https://github.com/nitlang/nit/tree/master/src git=https://github.com/nitlang/nit.git diff --git a/src/testing/testing_base.nit b/src/testing/testing_base.nit index b01d7dd..36ce1f9 100644 --- a/src/testing/testing_base.nit +++ b/src/testing/testing_base.nit @@ -198,6 +198,9 @@ abstract class UnitTest # The location where the error occurred, if it makes sense. var error_location: nullable Location = null is writable + # Additional noteworthy information when a test success. + var info: nullable String = null + # A colorful `[OK]` or `[KO]`. fun status_tag(color: nullable Bool): String do color = color or else true @@ -236,6 +239,10 @@ abstract class UnitTest else res = "{status_tag(color)} {full_name}" if more_message != null then res += more_message + var info = self.info + if info != null then + res += "\n {info}" + end end return res end diff --git a/src/testing/testing_suite.nit b/src/testing/testing_suite.nit index 309393c..a37d243 100644 --- a/src/testing/testing_suite.nit +++ b/src/testing/testing_suite.nit @@ -24,6 +24,8 @@ redef class ToolContext var opt_file = new OptionString("Specify test suite location", "-t", "--target-file") # --pattern var opt_pattern = new OptionString("Only run test case with name that match pattern", "-p", "--pattern") + # --autosav + var opt_autosav = new OptionBool("Automatically create/update .res files for black box testing", "--autosav") end # Used to test nitunit test files. @@ -269,7 +271,8 @@ class TestCase var test_file = test_suite.test_file var res_name = "{test_file}_{method_name.escape_to_c}" var res = toolcontext.safe_exec("{test_file}.bin {method_name} > '{res_name}.out1' 2>&1 '{res_name}.diff' 2>&1 1 then + toolcontext.info("Conflicting diffs: {savs.join(", ")}", 1) + error = "Conflicting expected output: {savs.join(", ", " and ")} all exist" + toolcontext.modelbuilder.failed_tests += 1 + else if not raw_output.is_empty then + toolcontext.info("No diff: {tries.join(", ", " or ")} not found", 1) + if toolcontext.opt_autosav.value then + var sav = tries.first + sav.dirname.mkdir + raw_output.write_to_file(sav) + info = "Expected output saved: {sav} (--autoupdate)" + end end end end diff --git a/tests/nitls.args b/tests/nitls.args index d87add0..5f5a31a 100644 --- a/tests/nitls.args +++ b/tests/nitls.args @@ -4,3 +4,5 @@ base_simple3.nit project1 -s base_simple3.nit project1 -M base_simple3.nit base_simple_import.nit -td project1/module3.nit project1/subdir/subdir2/subdir3/submodule.nit +test_prog --no-color +test_prog/game/excluded.nit test_prog/game/excluded_dir/more.nit -t --no-color diff --git a/tests/nitpick.args b/tests/nitpick.args index 396ac26..1ef81d1 100644 --- a/tests/nitpick.args +++ b/tests/nitpick.args @@ -1,3 +1,4 @@ --no-color -W test_advice_repeated_types.nit --no-color base_simple3.nit; echo $? --no-color error_mod_unk.nit; echo $? +--no-color test_prog diff --git a/tests/sav/nitdoc_args4.res b/tests/sav/nitdoc_args4.res index 01782ba..9238b51 100644 --- a/tests/sav/nitdoc_args4.res +++ b/tests/sav/nitdoc_args4.res @@ -1,8 +1,35 @@ +Empty README for group `excluded` (readme-warning) +Errors: 0. Warnings: 1. +MGroupPage excluded + # excluded.section + ## excluded.intro + ## excluded.concerns + ## excluded.concern + ## excluded.concern + ## excluded-.concern + ### excluded-.definition + #### excluded-.intros_redefs + ##### list.group + ###### excluded-.intros + ###### excluded-.redefs + +MModulePage excluded + # excluded.section + ## excluded-.intro + ## excluded-.importation + ### excluded-.graph + ### list.group + #### excluded-.imports + #### excluded-.clients + OverviewPage Overview # home.article ## packages.section + ### excluded.definition ### test_prog.definition +ReadmePage excluded + ReadmePage test_prog # mdarticle-0 @@ -1007,24 +1034,24 @@ MModulePage rpg #### test_prog__rpg__rpg.imports #### test_prog__rpg__rpg.clients -Generated 96 pages +Generated 99 pages list: - MPropertyPage: 58 (60.41%) - MClassPage: 20 (20.83%) - MModulePage: 8 (8.33%) - MGroupPage: 4 (4.16%) - ReadmePage: 4 (4.16%) - SearchPage: 1 (1.04%) - OverviewPage: 1 (1.04%) -Found 182 mentities + MPropertyPage: 58 (58.58%) + MClassPage: 20 (20.20%) + MModulePage: 9 (9.09%) + ReadmePage: 5 (5.05%) + MGroupPage: 5 (5.05%) + SearchPage: 1 (1.01%) + OverviewPage: 1 (1.01%) +Found 185 mentities list: - MMethodDef: 68 (37.36%) - MMethod: 57 (31.31%) - MClassDef: 22 (12.08%) - MClass: 20 (10.98%) - MModule: 8 (4.39%) - MGroup: 4 (2.19%) + MMethodDef: 68 (36.75%) + MMethod: 57 (30.81%) + MClassDef: 22 (11.89%) + MClass: 20 (10.81%) + MModule: 9 (4.86%) + MGroup: 5 (2.70%) + MPackage: 2 (1.08%) MVirtualTypeDef: 1 (0.54%) MVirtualTypeProp: 1 (0.54%) - MPackage: 1 (0.54%) quicksearch-list.js diff --git a/tests/sav/nitls_args7.res b/tests/sav/nitls_args7.res new file mode 100644 index 0000000..a0a686e --- /dev/null +++ b/tests/sav/nitls_args7.res @@ -0,0 +1,12 @@ +test_prog: Test program for model tools. (test_prog) +|--game: Gaming group (test_prog/game) +| `--game: A game abstraction for RPG. (test_prog/game/game.nit) +|--platform: Fictive Crappy Platform. (test_prog/platform) +| `--platform: Declares base types allowed on the platform. (test_prog/platform/platform.nit) +|--rpg: Role Playing Game group (test_prog/rpg) +| |--careers: Careers of the game. (test_prog/rpg/careers.nit) +| |--character: Characters are playable entity in the world. (test_prog/rpg/character.nit) +| |--combat: COmbat interactions between characters. (test_prog/rpg/combat.nit) +| |--races: Races of the game. (test_prog/rpg/races.nit) +| `--rpg: A worlg RPG abstraction. (test_prog/rpg/rpg.nit) +`--test_prog: A test program with a fake model to check model tools. (test_prog/test_prog.nit) diff --git a/tests/sav/nitls_args8.res b/tests/sav/nitls_args8.res new file mode 100644 index 0000000..b80e7ce --- /dev/null +++ b/tests/sav/nitls_args8.res @@ -0,0 +1,2 @@ +excluded (test_prog/game/excluded.nit) +more (test_prog/game/excluded_dir/more.nit) diff --git a/tests/sav/nitunit_args9.res b/tests/sav/nitunit_args9.res index 7d1f2bd2..773614a 100644 --- a/tests/sav/nitunit_args9.res +++ b/tests/sav/nitunit_args9.res @@ -1,4 +1,4 @@ -==== Test-suite of module test_nitunit4::test_nitunit4 | tests: 3 +==== Test-suite of module test_nitunit4::test_nitunit4 | tests: 4 [KO] test_nitunit4$TestTestSuite$test_foo test_nitunit4/test_nitunit4.nit:22,2--26,4: Runtime Error in file nitunit.out/gen_test_nitunit4.nit Output @@ -9,10 +9,10 @@ [OK] test_nitunit4$TestTestSuite$test_bar [KO] test_nitunit4$TestTestSuite$test_baz - test_nitunit4/test_nitunit4.nit:32,2--34,4: Difference with expected output: diff -u test_nitunit4/test_nitunit4.sav/test_baz.res nitunit.out/gen_test_nitunit4_test_baz.out1 + test_nitunit4/test_nitunit4.nit:32,2--34,4: Difference with expected output: diff -u test_nitunit4/test_baz.res nitunit.out/gen_test_nitunit4_test_baz.out1 Output Diff - --- expected:test_nitunit4/test_nitunit4.sav/test_baz.res + --- expected:test_nitunit4/test_baz.res +++ got:nitunit.out/gen_test_nitunit4_test_baz.out1 @@ -1 +1,3 @@ -Bad result file @@ -20,10 +20,17 @@ +Tested method +After Test +[KO] test_nitunit4$TestTestSuite$test_sav_conflict + test_nitunit4/test_nitunit4.nit:36,2--38,4: Conflicting expected output: test_nitunit4/test_nitunit4.sav/test_sav_conflict.res, test_nitunit4/sav/test_sav_conflict.res and test_nitunit4/test_sav_conflict.res all exist + Output + Before Test + Tested method + After Test -Docunits: Entities: 12; Documented ones: 0; With nitunits: 0 -Test suites: Classes: 1; Test Cases: 3; Failures: 2 -[FAILURE] 2/3 tests failed. + +Docunits: Entities: 13; Documented ones: 0; With nitunits: 0 +Test suites: Classes: 1; Test Cases: 4; Failures: 3 +[FAILURE] 3/4 tests failed. `nitunit.out` is not removed for investigation. Runtime Error in file nitunit.out/gen_test_nitunit4.nitBefore Test Tested method @@ -32,12 +39,15 @@ Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31) Before Test Tested method After Test -Difference with expected output: diff -u test_nitunit4/test_nitunit4.sav/test_baz.res nitunit.out/gen_test_nitunit4_test_baz.out1Diff ---- expected:test_nitunit4/test_nitunit4.sav/test_baz.res +Difference with expected output: diff -u test_nitunit4/test_baz.res nitunit.out/gen_test_nitunit4_test_baz.out1Diff +--- expected:test_nitunit4/test_baz.res +++ got:nitunit.out/gen_test_nitunit4_test_baz.out1 @@ -1 +1,3 @@ -Bad result file +Before Test +Tested method +After Test +Conflicting expected output: test_nitunit4/test_nitunit4.sav/test_sav_conflict.res, test_nitunit4/sav/test_sav_conflict.res and test_nitunit4/test_sav_conflict.res all existBefore Test +Tested method +After Test \ No newline at end of file diff --git a/tests/sav/test_neo_args1.res b/tests/sav/test_neo_args1.res index 4ac86da..fdc3be7 100644 --- a/tests/sav/test_neo_args1.res +++ b/tests/sav/test_neo_args1.res @@ -1,12 +1,12 @@ # mpackages: -test_prog +excluded test_prog ------------------------------------ -test_prog +excluded test_prog # mmodules: -careers character combat game platform races rpg test_prog +careers character combat excluded game platform races rpg test_prog ------------------------------------ -careers character combat game platform races rpg test_prog +careers character combat excluded game platform races rpg test_prog # mclasses: Alcoholic Bool Career Character Combatable Dwarf Elf Float Game Human Int List Magician Object Race Starter String Sys Warrior Weapon diff --git a/tests/sav/test_sort_perf_args1.res b/tests/sav/test_sort_perf_args1.res index 01532de..b1fe714 100644 --- a/tests/sav/test_sort_perf_args1.res +++ b/tests/sav/test_sort_perf_args1.res @@ -2,6 +2,9 @@ test_prog/ |--test_prog/README.md |--test_prog/game | |--test_prog/game/README.md +| |--test_prog/game/excluded.nit +| |--test_prog/game/excluded_dir +| | `--test_prog/game/excluded_dir/more.nit | `--test_prog/game/game.nit |--test_prog/package.ini |--test_prog/platform diff --git a/tests/test_nitunit4/sav/test_sav_conflict.res b/tests/test_nitunit4/sav/test_sav_conflict.res new file mode 100644 index 0000000..7b3a785 --- /dev/null +++ b/tests/test_nitunit4/sav/test_sav_conflict.res @@ -0,0 +1 @@ +BAD diff --git a/tests/test_nitunit4/test_nitunit4.sav/test_baz.res b/tests/test_nitunit4/test_baz.res similarity index 100% rename from tests/test_nitunit4/test_nitunit4.sav/test_baz.res rename to tests/test_nitunit4/test_baz.res diff --git a/tests/test_nitunit4/test_nitunit4.nit b/tests/test_nitunit4/test_nitunit4.nit index cd13aca..8864263 100644 --- a/tests/test_nitunit4/test_nitunit4.nit +++ b/tests/test_nitunit4/test_nitunit4.nit @@ -32,4 +32,8 @@ class TestTestSuite fun test_baz do print "Tested method" end + + fun test_sav_conflict do + print "Tested method" + end end diff --git a/tests/test_nitunit4/test_nitunit4.sav/test_sav_conflict.res b/tests/test_nitunit4/test_nitunit4.sav/test_sav_conflict.res new file mode 100644 index 0000000..7b3a785 --- /dev/null +++ b/tests/test_nitunit4/test_nitunit4.sav/test_sav_conflict.res @@ -0,0 +1 @@ +BAD diff --git a/tests/test_nitunit4/test_sav_conflict.res b/tests/test_nitunit4/test_sav_conflict.res new file mode 100644 index 0000000..7b3a785 --- /dev/null +++ b/tests/test_nitunit4/test_sav_conflict.res @@ -0,0 +1 @@ +BAD diff --git a/tests/test_prog/game/excluded.nit b/tests/test_prog/game/excluded.nit new file mode 100644 index 0000000..d296d4b --- /dev/null +++ b/tests/test_prog/game/excluded.nit @@ -0,0 +1 @@ +This is not a valid Nit program diff --git a/tests/test_prog/game/excluded_dir/more.nit b/tests/test_prog/game/excluded_dir/more.nit new file mode 100644 index 0000000..d296d4b --- /dev/null +++ b/tests/test_prog/game/excluded_dir/more.nit @@ -0,0 +1 @@ +This is not a valid Nit program diff --git a/tests/test_prog/package.ini b/tests/test_prog/package.ini index ff4b70d..bfcd472 100644 --- a/tests/test_prog/package.ini +++ b/tests/test_prog/package.ini @@ -5,6 +5,8 @@ tags=test,game maintainer=John Doe (http://www.example.com/~jdoe), Spider-Man more_contributors=Riri , Fifi (http://www.example.com/~fifi), Loulou license=Apache-2.0 +[source] +exclude=game/excluded.nit:game/excluded_dir [upstream] browse=https://github.com/nitlang/nit/tree/master/tests/test_prog git=https://github.com/nitlang/nit.git