mutest 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.buildkite/hooks/pre-command +3 -0
- data/.buildkite/pipeline.yml +51 -0
- data/.gitattributes +1 -0
- data/.gitignore +38 -0
- data/.rspec +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +216 -0
- data/Gemfile.shared +3 -0
- data/LICENSE +21 -0
- data/README.md +8 -0
- data/Rakefile +24 -0
- data/bin/mutest +39 -0
- data/build/Dockerfile +71 -0
- data/build/docker-bootstrap.sh +85 -0
- data/build/docker-exec +29 -0
- data/build/make-docker +3 -0
- data/build/ruby_matrix +1 -0
- data/build/run +5 -0
- data/build/strict-mode.sh +16 -0
- data/circle.yml +7 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/reek.yml +137 -0
- data/config/rubocop.yml +395 -0
- data/config/triage.yml +2 -0
- data/config/yardstick.yml +2 -0
- data/lib/mutest.rb +243 -0
- data/lib/mutest/actor.rb +52 -0
- data/lib/mutest/actor/env.rb +28 -0
- data/lib/mutest/actor/mailbox.rb +31 -0
- data/lib/mutest/actor/receiver.rb +39 -0
- data/lib/mutest/actor/sender.rb +22 -0
- data/lib/mutest/ast.rb +44 -0
- data/lib/mutest/ast/meta.rb +7 -0
- data/lib/mutest/ast/meta/const.rb +22 -0
- data/lib/mutest/ast/meta/optarg.rb +24 -0
- data/lib/mutest/ast/meta/resbody.rb +15 -0
- data/lib/mutest/ast/meta/restarg.rb +15 -0
- data/lib/mutest/ast/meta/send.rb +89 -0
- data/lib/mutest/ast/meta/symbol.rb +15 -0
- data/lib/mutest/ast/named_children.rb +86 -0
- data/lib/mutest/ast/node_predicates.rb +17 -0
- data/lib/mutest/ast/nodes.rb +22 -0
- data/lib/mutest/ast/regexp.rb +50 -0
- data/lib/mutest/ast/regexp/transformer.rb +184 -0
- data/lib/mutest/ast/regexp/transformer/alternative.rb +39 -0
- data/lib/mutest/ast/regexp/transformer/character_set.rb +46 -0
- data/lib/mutest/ast/regexp/transformer/direct.rb +101 -0
- data/lib/mutest/ast/regexp/transformer/options_group.rb +65 -0
- data/lib/mutest/ast/regexp/transformer/quantifier.rb +112 -0
- data/lib/mutest/ast/regexp/transformer/recursive.rb +50 -0
- data/lib/mutest/ast/regexp/transformer/root.rb +28 -0
- data/lib/mutest/ast/regexp/transformer/text.rb +55 -0
- data/lib/mutest/ast/sexp.rb +26 -0
- data/lib/mutest/ast/types.rb +140 -0
- data/lib/mutest/cli.rb +196 -0
- data/lib/mutest/color.rb +39 -0
- data/lib/mutest/config.rb +28 -0
- data/lib/mutest/context.rb +98 -0
- data/lib/mutest/diff.rb +111 -0
- data/lib/mutest/env.rb +59 -0
- data/lib/mutest/env/bootstrap.rb +159 -0
- data/lib/mutest/expression.rb +55 -0
- data/lib/mutest/expression/method.rb +54 -0
- data/lib/mutest/expression/methods.rb +58 -0
- data/lib/mutest/expression/namespace.rb +75 -0
- data/lib/mutest/expression/parser.rb +64 -0
- data/lib/mutest/integration.rb +75 -0
- data/lib/mutest/isolation.rb +11 -0
- data/lib/mutest/isolation/fork.rb +72 -0
- data/lib/mutest/isolation/none.rb +23 -0
- data/lib/mutest/loader.rb +27 -0
- data/lib/mutest/matcher.rb +14 -0
- data/lib/mutest/matcher/chain.rb +19 -0
- data/lib/mutest/matcher/compiler.rb +55 -0
- data/lib/mutest/matcher/config.rb +81 -0
- data/lib/mutest/matcher/filter.rb +19 -0
- data/lib/mutest/matcher/method.rb +138 -0
- data/lib/mutest/matcher/method/instance.rb +63 -0
- data/lib/mutest/matcher/method/singleton.rb +88 -0
- data/lib/mutest/matcher/methods.rb +109 -0
- data/lib/mutest/matcher/namespace.rb +41 -0
- data/lib/mutest/matcher/null.rb +17 -0
- data/lib/mutest/matcher/scope.rb +38 -0
- data/lib/mutest/matcher/static.rb +15 -0
- data/lib/mutest/meta.rb +33 -0
- data/lib/mutest/meta/example.rb +32 -0
- data/lib/mutest/meta/example/dsl.rb +107 -0
- data/lib/mutest/meta/example/verification.rb +85 -0
- data/lib/mutest/mutation.rb +101 -0
- data/lib/mutest/mutator.rb +117 -0
- data/lib/mutest/mutator/node.rb +166 -0
- data/lib/mutest/mutator/node/and_asgn.rb +25 -0
- data/lib/mutest/mutator/node/argument.rb +68 -0
- data/lib/mutest/mutator/node/arguments.rb +90 -0
- data/lib/mutest/mutator/node/begin.rb +21 -0
- data/lib/mutest/mutator/node/binary.rb +64 -0
- data/lib/mutest/mutator/node/block.rb +51 -0
- data/lib/mutest/mutator/node/break.rb +21 -0
- data/lib/mutest/mutator/node/case.rb +47 -0
- data/lib/mutest/mutator/node/class.rb +21 -0
- data/lib/mutest/mutator/node/conditional_loop.rb +25 -0
- data/lib/mutest/mutator/node/const.rb +23 -0
- data/lib/mutest/mutator/node/define.rb +79 -0
- data/lib/mutest/mutator/node/defined.rb +24 -0
- data/lib/mutest/mutator/node/dstr.rb +20 -0
- data/lib/mutest/mutator/node/dsym.rb +20 -0
- data/lib/mutest/mutator/node/generic.rb +77 -0
- data/lib/mutest/mutator/node/if.rb +57 -0
- data/lib/mutest/mutator/node/kwbegin.rb +20 -0
- data/lib/mutest/mutator/node/literal.rb +19 -0
- data/lib/mutest/mutator/node/literal/array.rb +37 -0
- data/lib/mutest/mutator/node/literal/boolean.rb +27 -0
- data/lib/mutest/mutator/node/literal/fixnum.rb +36 -0
- data/lib/mutest/mutator/node/literal/float.rb +45 -0
- data/lib/mutest/mutator/node/literal/hash.rb +52 -0
- data/lib/mutest/mutator/node/literal/nil.rb +20 -0
- data/lib/mutest/mutator/node/literal/range.rb +38 -0
- data/lib/mutest/mutator/node/literal/regex.rb +76 -0
- data/lib/mutest/mutator/node/literal/string.rb +21 -0
- data/lib/mutest/mutator/node/literal/symbol.rb +26 -0
- data/lib/mutest/mutator/node/masgn.rb +21 -0
- data/lib/mutest/mutator/node/match_current_line.rb +22 -0
- data/lib/mutest/mutator/node/mlhs.rb +21 -0
- data/lib/mutest/mutator/node/named_value/access.rb +54 -0
- data/lib/mutest/mutator/node/named_value/constant_assignment.rb +42 -0
- data/lib/mutest/mutator/node/named_value/variable_assignment.rb +47 -0
- data/lib/mutest/mutator/node/next.rb +22 -0
- data/lib/mutest/mutator/node/noop.rb +19 -0
- data/lib/mutest/mutator/node/nthref.rb +22 -0
- data/lib/mutest/mutator/node/op_asgn.rb +50 -0
- data/lib/mutest/mutator/node/or_asgn.rb +26 -0
- data/lib/mutest/mutator/node/regexp.rb +33 -0
- data/lib/mutest/mutator/node/regexp/alternation_meta.rb +21 -0
- data/lib/mutest/mutator/node/regexp/capture_group.rb +26 -0
- data/lib/mutest/mutator/node/regexp/character_type.rb +29 -0
- data/lib/mutest/mutator/node/regexp/end_of_line_anchor.rb +21 -0
- data/lib/mutest/mutator/node/regexp/end_of_string_or_before_end_of_line_anchor.rb +21 -0
- data/lib/mutest/mutator/node/regexp/one_or_more.rb +29 -0
- data/lib/mutest/mutator/node/regexp/zero_or_more.rb +29 -0
- data/lib/mutest/mutator/node/regopt.rb +28 -0
- data/lib/mutest/mutator/node/resbody.rb +34 -0
- data/lib/mutest/mutator/node/rescue.rb +69 -0
- data/lib/mutest/mutator/node/return.rb +24 -0
- data/lib/mutest/mutator/node/send.rb +270 -0
- data/lib/mutest/mutator/node/send/attribute_assignment.rb +39 -0
- data/lib/mutest/mutator/node/send/binary.rb +45 -0
- data/lib/mutest/mutator/node/send/conditional.rb +21 -0
- data/lib/mutest/mutator/node/send/index.rb +47 -0
- data/lib/mutest/mutator/node/splat.rb +23 -0
- data/lib/mutest/mutator/node/super.rb +24 -0
- data/lib/mutest/mutator/node/when.rb +60 -0
- data/lib/mutest/mutator/node/yield.rb +21 -0
- data/lib/mutest/mutator/node/zsuper.rb +20 -0
- data/lib/mutest/mutator/util.rb +11 -0
- data/lib/mutest/mutator/util/array.rb +42 -0
- data/lib/mutest/mutator/util/symbol.rb +19 -0
- data/lib/mutest/parallel.rb +89 -0
- data/lib/mutest/parallel/master.rb +181 -0
- data/lib/mutest/parallel/source.rb +57 -0
- data/lib/mutest/parallel/worker.rb +76 -0
- data/lib/mutest/parser.rb +22 -0
- data/lib/mutest/registry.rb +43 -0
- data/lib/mutest/reporter.rb +39 -0
- data/lib/mutest/reporter/cli.rb +87 -0
- data/lib/mutest/reporter/cli/format.rb +135 -0
- data/lib/mutest/reporter/cli/printer.rb +124 -0
- data/lib/mutest/reporter/cli/printer/config.rb +24 -0
- data/lib/mutest/reporter/cli/printer/env_progress.rb +76 -0
- data/lib/mutest/reporter/cli/printer/env_result.rb +20 -0
- data/lib/mutest/reporter/cli/printer/mutation_progress_result.rb +31 -0
- data/lib/mutest/reporter/cli/printer/mutation_result.rb +127 -0
- data/lib/mutest/reporter/cli/printer/status.rb +49 -0
- data/lib/mutest/reporter/cli/printer/status_progressive.rb +46 -0
- data/lib/mutest/reporter/cli/printer/subject_progress.rb +65 -0
- data/lib/mutest/reporter/cli/printer/subject_result.rb +23 -0
- data/lib/mutest/reporter/cli/printer/test_result.rb +28 -0
- data/lib/mutest/reporter/cli/tput.rb +43 -0
- data/lib/mutest/reporter/null.rb +14 -0
- data/lib/mutest/reporter/sequence.rb +24 -0
- data/lib/mutest/repository.rb +80 -0
- data/lib/mutest/require_highjack.rb +24 -0
- data/lib/mutest/result.rb +212 -0
- data/lib/mutest/runner.rb +81 -0
- data/lib/mutest/runner/sink.rb +63 -0
- data/lib/mutest/scope.rb +6 -0
- data/lib/mutest/selector.rb +13 -0
- data/lib/mutest/selector/expression.rb +25 -0
- data/lib/mutest/source_file.rb +47 -0
- data/lib/mutest/subject.rb +94 -0
- data/lib/mutest/subject/method.rb +42 -0
- data/lib/mutest/subject/method/instance.rb +43 -0
- data/lib/mutest/subject/method/singleton.rb +19 -0
- data/lib/mutest/test.rb +14 -0
- data/lib/mutest/util.rb +18 -0
- data/lib/mutest/version.rb +4 -0
- data/lib/mutest/warning_filter.rb +58 -0
- data/lib/mutest/zombifier.rb +119 -0
- data/meta/and.rb +13 -0
- data/meta/and_asgn.rb +12 -0
- data/meta/array.rb +28 -0
- data/meta/begin.rb +19 -0
- data/meta/block.rb +104 -0
- data/meta/block_pass.rb +6 -0
- data/meta/blockarg.rb +8 -0
- data/meta/break.rb +8 -0
- data/meta/case.rb +221 -0
- data/meta/casgn.rb +26 -0
- data/meta/cbase.rb +6 -0
- data/meta/class.rb +10 -0
- data/meta/const.rb +15 -0
- data/meta/csend.rb +8 -0
- data/meta/cvar.rb +5 -0
- data/meta/cvasgn.rb +8 -0
- data/meta/date.rb +57 -0
- data/meta/def.rb +260 -0
- data/meta/defined.rb +7 -0
- data/meta/dstr.rb +11 -0
- data/meta/dsym.rb +12 -0
- data/meta/ensure.rb +7 -0
- data/meta/false.rb +6 -0
- data/meta/float.rb +35 -0
- data/meta/gvar.rb +5 -0
- data/meta/gvasgn.rb +8 -0
- data/meta/hash.rb +22 -0
- data/meta/if.rb +75 -0
- data/meta/int.rb +16 -0
- data/meta/ivar.rb +6 -0
- data/meta/ivasgn.rb +21 -0
- data/meta/kwarg.rb +8 -0
- data/meta/kwbegin.rb +7 -0
- data/meta/kwoptarg.rb +11 -0
- data/meta/kwrestarg.rb +17 -0
- data/meta/lvar.rb +14 -0
- data/meta/lvasgn.rb +8 -0
- data/meta/masgn.rb +5 -0
- data/meta/match_current_line.rb +13 -0
- data/meta/next.rb +9 -0
- data/meta/nil.rb +3 -0
- data/meta/nthref.rb +12 -0
- data/meta/op_assgn.rb +39 -0
- data/meta/or.rb +13 -0
- data/meta/or_asgn.rb +48 -0
- data/meta/range.rb +37 -0
- data/meta/redo.rb +3 -0
- data/meta/regexp.rb +84 -0
- data/meta/regexp/character_types.rb +20 -0
- data/meta/regexp/regexp_alternation_meta.rb +11 -0
- data/meta/regexp/regexp_bol_anchor.rb +8 -0
- data/meta/regexp/regexp_bos_anchor.rb +16 -0
- data/meta/regexp/regexp_capture_group.rb +17 -0
- data/meta/regexp/regexp_eol_anchor.rb +8 -0
- data/meta/regexp/regexp_eos_anchor.rb +6 -0
- data/meta/regexp/regexp_eos_ob_eol_anchor.rb +8 -0
- data/meta/regexp/regexp_one_or_more.rb +32 -0
- data/meta/regexp/regexp_root_expression.rb +8 -0
- data/meta/regexp/regexp_zero_or_more.rb +32 -0
- data/meta/regopt.rb +8 -0
- data/meta/rescue.rb +87 -0
- data/meta/restarg.rb +9 -0
- data/meta/return.rb +14 -0
- data/meta/self.rb +5 -0
- data/meta/send.rb +849 -0
- data/meta/str.rb +5 -0
- data/meta/super.rb +25 -0
- data/meta/sym.rb +6 -0
- data/meta/true.rb +6 -0
- data/meta/until.rb +15 -0
- data/meta/while.rb +24 -0
- data/meta/yield.rb +8 -0
- data/mutest-rspec.gemspec +22 -0
- data/mutest.gemspec +45 -0
- data/spec/integration/mutest/corpus_spec.rb +18 -0
- data/spec/integration/mutest/isolation/fork_spec.rb +8 -0
- data/spec/integration/mutest/null_spec.rb +13 -0
- data/spec/integration/mutest/rspec_spec.rb +11 -0
- data/spec/integration/mutest/test_mutator_handles_types_spec.rb +7 -0
- data/spec/integrations.yml +32 -0
- data/spec/rcov.opts +7 -0
- data/spec/shared/framework_integration_behavior.rb +44 -0
- data/spec/shared/method_matcher_behavior.rb +49 -0
- data/spec/spec_helper.rb +70 -0
- data/spec/support/compress_helper.rb +9 -0
- data/spec/support/corpus.rb +331 -0
- data/spec/support/fake_actor.rb +107 -0
- data/spec/support/file_system.rb +60 -0
- data/spec/support/ice_nine_config.rb +8 -0
- data/spec/support/rb_bug.rb +15 -0
- data/spec/support/ruby_vm.rb +82 -0
- data/spec/support/shared_context.rb +125 -0
- data/spec/support/test_app.rb +5 -0
- data/spec/support/warning.rb +73 -0
- data/spec/support/warnings.yml +5 -0
- data/spec/support/xspec.rb +175 -0
- data/spec/unit/mutest/actor/binding_spec.rb +32 -0
- data/spec/unit/mutest/actor/env_spec.rb +29 -0
- data/spec/unit/mutest/actor/mailbox_spec.rb +25 -0
- data/spec/unit/mutest/actor/message_spec.rb +22 -0
- data/spec/unit/mutest/actor/receiver_spec.rb +56 -0
- data/spec/unit/mutest/actor/sender_spec.rb +22 -0
- data/spec/unit/mutest/ast/meta/optarg_spec.rb +21 -0
- data/spec/unit/mutest/ast/meta/send/proc_predicate_spec.rb +28 -0
- data/spec/unit/mutest/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb +37 -0
- data/spec/unit/mutest/ast/meta/send_spec.rb +42 -0
- data/spec/unit/mutest/ast/named_children_spec.rb +87 -0
- data/spec/unit/mutest/ast/regexp/parse_spec.rb +5 -0
- data/spec/unit/mutest/ast/regexp/supported_predicate_spec.rb +14 -0
- data/spec/unit/mutest/ast/regexp/transformer/lookup_table/table_spec.rb +19 -0
- data/spec/unit/mutest/ast/regexp/transformer/lookup_table_spec.rb +33 -0
- data/spec/unit/mutest/ast/regexp/transformer_spec.rb +19 -0
- data/spec/unit/mutest/ast/regexp_spec.rb +625 -0
- data/spec/unit/mutest/ast/sexp_spec.rb +36 -0
- data/spec/unit/mutest/ast_spec.rb +55 -0
- data/spec/unit/mutest/cli_spec.rb +247 -0
- data/spec/unit/mutest/context_spec.rb +141 -0
- data/spec/unit/mutest/diff_spec.rb +185 -0
- data/spec/unit/mutest/env/bootstrap_spec.rb +188 -0
- data/spec/unit/mutest/env_spec.rb +100 -0
- data/spec/unit/mutest/expression/method_spec.rb +44 -0
- data/spec/unit/mutest/expression/methods_spec.rb +59 -0
- data/spec/unit/mutest/expression/namespace/exact_spec.rb +26 -0
- data/spec/unit/mutest/expression/namespace/recursive_spec.rb +64 -0
- data/spec/unit/mutest/expression/parser_spec.rb +67 -0
- data/spec/unit/mutest/expression_spec.rb +45 -0
- data/spec/unit/mutest/integration/null_spec.rb +28 -0
- data/spec/unit/mutest/integration/rspec_spec.rb +197 -0
- data/spec/unit/mutest/integration_spec.rb +26 -0
- data/spec/unit/mutest/isolation/fork_spec.rb +155 -0
- data/spec/unit/mutest/isolation/none_spec.rb +16 -0
- data/spec/unit/mutest/loader_spec.rb +42 -0
- data/spec/unit/mutest/matcher/chain_spec.rb +24 -0
- data/spec/unit/mutest/matcher/compiler/subject_prefix_spec.rb +24 -0
- data/spec/unit/mutest/matcher/compiler_spec.rb +76 -0
- data/spec/unit/mutest/matcher/config_spec.rb +45 -0
- data/spec/unit/mutest/matcher/filter_spec.rb +20 -0
- data/spec/unit/mutest/matcher/method/instance_spec.rb +125 -0
- data/spec/unit/mutest/matcher/method/singleton_spec.rb +85 -0
- data/spec/unit/mutest/matcher/methods/instance_spec.rb +58 -0
- data/spec/unit/mutest/matcher/methods/singleton_spec.rb +54 -0
- data/spec/unit/mutest/matcher/namespace_spec.rb +35 -0
- data/spec/unit/mutest/matcher/null_spec.rb +10 -0
- data/spec/unit/mutest/matcher/scope_spec.rb +33 -0
- data/spec/unit/mutest/matcher/static_spec.rb +11 -0
- data/spec/unit/mutest/meta/example/dsl_spec.rb +123 -0
- data/spec/unit/mutest/meta/example/verification_spec.rb +120 -0
- data/spec/unit/mutest/meta/example_spec.rb +32 -0
- data/spec/unit/mutest/mutation_spec.rb +129 -0
- data/spec/unit/mutest/mutator/node_spec.rb +43 -0
- data/spec/unit/mutest/mutator_spec.rb +30 -0
- data/spec/unit/mutest/parallel/driver_spec.rb +26 -0
- data/spec/unit/mutest/parallel/master_spec.rb +335 -0
- data/spec/unit/mutest/parallel/source/array_spec.rb +47 -0
- data/spec/unit/mutest/parallel/worker_spec.rb +65 -0
- data/spec/unit/mutest/parallel_spec.rb +16 -0
- data/spec/unit/mutest/parser_spec.rb +24 -0
- data/spec/unit/mutest/registry_spec.rb +45 -0
- data/spec/unit/mutest/reporter/cli/printer/config_spec.rb +29 -0
- data/spec/unit/mutest/reporter/cli/printer/env_progress_spec.rb +74 -0
- data/spec/unit/mutest/reporter/cli/printer/env_result_spec.rb +35 -0
- data/spec/unit/mutest/reporter/cli/printer/mutation_progress_result_spec.rb +23 -0
- data/spec/unit/mutest/reporter/cli/printer/mutation_result_spec.rb +110 -0
- data/spec/unit/mutest/reporter/cli/printer/status_progressive_spec.rb +43 -0
- data/spec/unit/mutest/reporter/cli/printer/status_spec.rb +119 -0
- data/spec/unit/mutest/reporter/cli/printer/subject_progress_spec.rb +34 -0
- data/spec/unit/mutest/reporter/cli/printer/subject_result_spec.rb +37 -0
- data/spec/unit/mutest/reporter/cli/printer/test_result_spec.rb +14 -0
- data/spec/unit/mutest/reporter/cli/printer_spec.rb +161 -0
- data/spec/unit/mutest/reporter/cli/tput_spec.rb +48 -0
- data/spec/unit/mutest/reporter/cli_spec.rb +212 -0
- data/spec/unit/mutest/reporter/null_spec.rb +12 -0
- data/spec/unit/mutest/reporter/sequence_spec.rb +29 -0
- data/spec/unit/mutest/repository/diff_spec.rb +106 -0
- data/spec/unit/mutest/repository/subject_filter_spec.rb +28 -0
- data/spec/unit/mutest/require_highjack_spec.rb +71 -0
- data/spec/unit/mutest/result/class_methods_spec.rb +49 -0
- data/spec/unit/mutest/result/env_spec.rb +82 -0
- data/spec/unit/mutest/result/mutation_spec.rb +37 -0
- data/spec/unit/mutest/result/subject_spec.rb +109 -0
- data/spec/unit/mutest/result_spec.rb +31 -0
- data/spec/unit/mutest/runner/sink_spec.rb +172 -0
- data/spec/unit/mutest/runner_spec.rb +69 -0
- data/spec/unit/mutest/selector/expression_spec.rb +59 -0
- data/spec/unit/mutest/source_file_spec.rb +42 -0
- data/spec/unit/mutest/subject/method/instance/memoized_spec.rb +78 -0
- data/spec/unit/mutest/subject/method/instance_spec.rb +64 -0
- data/spec/unit/mutest/subject/method/singleton_spec.rb +51 -0
- data/spec/unit/mutest/subject_spec.rb +87 -0
- data/spec/unit/mutest/util/one_spec.rb +20 -0
- data/spec/unit/mutest/warning_filter_spec.rb +99 -0
- data/spec/unit/mutest/zombifier_spec.rb +120 -0
- data/spec/unit/mutest_spec.rb +15 -0
- data/test_app/.rspec +1 -0
- data/test_app/Gemfile.rspec3.4 +7 -0
- data/test_app/Gemfile.rspec3.5 +7 -0
- data/test_app/lib/test_app.rb +109 -0
- data/test_app/lib/test_app/literal.rb +40 -0
- data/test_app/spec/spec_helper.rb +9 -0
- data/test_app/spec/unit/test_app/literal_spec.rb +20 -0
- metadata +784 -9
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
class Reporter
|
|
3
|
+
class CLI
|
|
4
|
+
class Printer
|
|
5
|
+
# Reporter for progressive output format on scheduler Status objects
|
|
6
|
+
class StatusProgressive < self
|
|
7
|
+
FORMAT = '(%02d/%02d) %3d%% - killtime: %0.02fs runtime: %0.02fs overhead: %0.02fs'.freeze
|
|
8
|
+
|
|
9
|
+
delegate(
|
|
10
|
+
:coverage,
|
|
11
|
+
:runtime,
|
|
12
|
+
:amount_mutations_killed,
|
|
13
|
+
:amount_mutations,
|
|
14
|
+
:amount_mutation_results,
|
|
15
|
+
:killtime,
|
|
16
|
+
:overhead
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# Run printer
|
|
20
|
+
#
|
|
21
|
+
# @return [undefined]
|
|
22
|
+
def run
|
|
23
|
+
status(
|
|
24
|
+
FORMAT,
|
|
25
|
+
amount_mutations_killed,
|
|
26
|
+
amount_mutations,
|
|
27
|
+
coverage * 100,
|
|
28
|
+
killtime,
|
|
29
|
+
runtime,
|
|
30
|
+
overhead
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
# Object being printed
|
|
37
|
+
#
|
|
38
|
+
# @return [Result::Env]
|
|
39
|
+
def object
|
|
40
|
+
super().payload
|
|
41
|
+
end
|
|
42
|
+
end # StatusProgressive
|
|
43
|
+
end # Printer
|
|
44
|
+
end # CLI
|
|
45
|
+
end # Reporter
|
|
46
|
+
end # Mutest
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
class Reporter
|
|
3
|
+
class CLI
|
|
4
|
+
class Printer
|
|
5
|
+
# Reporter for subject progress
|
|
6
|
+
class SubjectProgress < self
|
|
7
|
+
FORMAT = '(%02d/%02d) %3d%% - killtime: %0.02fs runtime: %0.02fs overhead: %0.02fs'.freeze
|
|
8
|
+
|
|
9
|
+
delegate(
|
|
10
|
+
:tests,
|
|
11
|
+
:subject,
|
|
12
|
+
:coverage,
|
|
13
|
+
:runtime,
|
|
14
|
+
:amount_mutations_killed,
|
|
15
|
+
:amount_mutations,
|
|
16
|
+
:amount_mutation_results,
|
|
17
|
+
:killtime,
|
|
18
|
+
:overhead
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# Run printer
|
|
22
|
+
#
|
|
23
|
+
# @return [undefined]
|
|
24
|
+
def run
|
|
25
|
+
puts("#{subject.identification} mutations: #{amount_mutations}")
|
|
26
|
+
print_mutation_results
|
|
27
|
+
print_progress_bar_finish
|
|
28
|
+
print_stats
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
# Print stats
|
|
34
|
+
#
|
|
35
|
+
# @return [undefined]
|
|
36
|
+
def print_stats
|
|
37
|
+
status(
|
|
38
|
+
FORMAT,
|
|
39
|
+
amount_mutations_killed,
|
|
40
|
+
amount_mutations,
|
|
41
|
+
coverage * 100,
|
|
42
|
+
killtime,
|
|
43
|
+
runtime,
|
|
44
|
+
overhead
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Print progress bar finish
|
|
49
|
+
#
|
|
50
|
+
# @return [undefined]
|
|
51
|
+
def print_progress_bar_finish
|
|
52
|
+
puts(nil) unless amount_mutation_results.zero?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Print mutation results
|
|
56
|
+
#
|
|
57
|
+
# @return [undefined]
|
|
58
|
+
def print_mutation_results
|
|
59
|
+
visit_collection(MutationProgressResult, object.mutation_results)
|
|
60
|
+
end
|
|
61
|
+
end # SubjectProgress
|
|
62
|
+
end # Printer
|
|
63
|
+
end # CLI
|
|
64
|
+
end # Reporter
|
|
65
|
+
end # Mutest
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
class Reporter
|
|
3
|
+
class CLI
|
|
4
|
+
class Printer
|
|
5
|
+
# Subject result printer
|
|
6
|
+
class SubjectResult < self
|
|
7
|
+
delegate :subject, :alive_mutation_results, :tests
|
|
8
|
+
|
|
9
|
+
# Run report printer
|
|
10
|
+
#
|
|
11
|
+
# @return [undefined]
|
|
12
|
+
def run
|
|
13
|
+
status(subject.identification)
|
|
14
|
+
tests.each do |test|
|
|
15
|
+
puts("- #{test.identification}")
|
|
16
|
+
end
|
|
17
|
+
visit_collection(MutationResult, alive_mutation_results)
|
|
18
|
+
end
|
|
19
|
+
end # SubjectResult
|
|
20
|
+
end # Printer
|
|
21
|
+
end # CLI
|
|
22
|
+
end # Reporter
|
|
23
|
+
end # Mutest
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
class Reporter
|
|
3
|
+
class CLI
|
|
4
|
+
class Printer
|
|
5
|
+
# Test result reporter
|
|
6
|
+
class TestResult < self
|
|
7
|
+
delegate :tests, :runtime
|
|
8
|
+
|
|
9
|
+
STATUS_FORMAT = '- %d @ runtime: %s'.freeze
|
|
10
|
+
OUTPUT_HEADER = 'Test Output:'.freeze
|
|
11
|
+
TEST_FORMAT = ' - %s'.freeze
|
|
12
|
+
|
|
13
|
+
# Run test result reporter
|
|
14
|
+
#
|
|
15
|
+
# @return [undefined]
|
|
16
|
+
def run
|
|
17
|
+
info(STATUS_FORMAT, tests.length, runtime)
|
|
18
|
+
tests.each do |test|
|
|
19
|
+
info(TEST_FORMAT, test.identification)
|
|
20
|
+
end
|
|
21
|
+
puts(OUTPUT_HEADER)
|
|
22
|
+
puts(object.output)
|
|
23
|
+
end
|
|
24
|
+
end # TestResult
|
|
25
|
+
end # Printer
|
|
26
|
+
end # CLI
|
|
27
|
+
end # Reporter
|
|
28
|
+
end # Mutest
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
class Reporter
|
|
3
|
+
class CLI
|
|
4
|
+
# Interface to the optionally present tput binary
|
|
5
|
+
class Tput
|
|
6
|
+
include Adamantium, Concord::Public.new(:prepare, :restore)
|
|
7
|
+
|
|
8
|
+
private_class_method :new
|
|
9
|
+
|
|
10
|
+
# Detected tput support
|
|
11
|
+
#
|
|
12
|
+
# @return [Tput]
|
|
13
|
+
# if tput support is present
|
|
14
|
+
#
|
|
15
|
+
# @return [nil]
|
|
16
|
+
# otherwise
|
|
17
|
+
def self.detect
|
|
18
|
+
reset = capture('tput reset')
|
|
19
|
+
save = capture('tput sc') if reset
|
|
20
|
+
restore = capture('tput rc') if save
|
|
21
|
+
clean = capture('tput ed') || capture('tput cd') if restore
|
|
22
|
+
new(reset + save, restore + clean) if clean
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Capture output
|
|
26
|
+
#
|
|
27
|
+
# @param [String] command
|
|
28
|
+
# command to run
|
|
29
|
+
#
|
|
30
|
+
# @return [String]
|
|
31
|
+
# stdout of command on success
|
|
32
|
+
#
|
|
33
|
+
# @return [nil]
|
|
34
|
+
# otherwise
|
|
35
|
+
def self.capture(command)
|
|
36
|
+
stdout, _stderr, exitstatus = Open3.capture3(command)
|
|
37
|
+
stdout if exitstatus.success?
|
|
38
|
+
end
|
|
39
|
+
private_class_method :capture
|
|
40
|
+
end # Tput
|
|
41
|
+
end # CLI
|
|
42
|
+
end # Reporter
|
|
43
|
+
end # Mutest
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
class Reporter
|
|
3
|
+
class Sequence < self
|
|
4
|
+
include Concord.new(:reporters)
|
|
5
|
+
|
|
6
|
+
%i[warn progress report start].each do |name|
|
|
7
|
+
define_method(name) do |value|
|
|
8
|
+
reporters.each do |reporter|
|
|
9
|
+
reporter.public_send(name, value)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
self
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Minimum reporter delay
|
|
17
|
+
#
|
|
18
|
+
# @return [Float]
|
|
19
|
+
def delay
|
|
20
|
+
reporters.map(&:delay).min
|
|
21
|
+
end
|
|
22
|
+
end # Sequence
|
|
23
|
+
end # Reporter
|
|
24
|
+
end # Mutest
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
module Repository
|
|
3
|
+
# Error raised on repository interaction problems
|
|
4
|
+
RepositoryError = Class.new(RuntimeError)
|
|
5
|
+
|
|
6
|
+
# Subject filter based on repository diff
|
|
7
|
+
class SubjectFilter
|
|
8
|
+
include Adamantium, Concord.new(:diff)
|
|
9
|
+
|
|
10
|
+
# Test if subject was touched in diff
|
|
11
|
+
#
|
|
12
|
+
# @param [Subject] subject
|
|
13
|
+
#
|
|
14
|
+
# @return [Boolean]
|
|
15
|
+
def call(subject)
|
|
16
|
+
diff.touches?(subject.source_path, subject.source_lines)
|
|
17
|
+
end
|
|
18
|
+
end # SubjectFilter
|
|
19
|
+
|
|
20
|
+
# Diff between two objects in repository
|
|
21
|
+
class Diff
|
|
22
|
+
include Adamantium, Anima.new(:config, :from, :to)
|
|
23
|
+
|
|
24
|
+
HEAD = 'HEAD'.freeze
|
|
25
|
+
|
|
26
|
+
# Test if diff changes file at line range
|
|
27
|
+
#
|
|
28
|
+
# @param [Pathname] path
|
|
29
|
+
# @param [Range<Fixnum>] line_range
|
|
30
|
+
#
|
|
31
|
+
# @return [Boolean]
|
|
32
|
+
#
|
|
33
|
+
# @raise [RepositoryError]
|
|
34
|
+
# when git command failed
|
|
35
|
+
def touches?(path, line_range)
|
|
36
|
+
return false unless within_working_directory?(path) && tracks?(path)
|
|
37
|
+
|
|
38
|
+
command = %W[
|
|
39
|
+
git log
|
|
40
|
+
#{from}...#{to}
|
|
41
|
+
-L #{line_range.begin},#{line_range.end}:#{path}
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
stdout, status = config.open3.capture2(*command, binmode: true)
|
|
45
|
+
|
|
46
|
+
fail RepositoryError, "Command #{command} failed!" unless status.success?
|
|
47
|
+
|
|
48
|
+
!stdout.empty?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
# Test if path is tracked in repository
|
|
54
|
+
#
|
|
55
|
+
# FIXME: Cache results, to avoid spending time on producing redundant results.
|
|
56
|
+
#
|
|
57
|
+
# @param [Pathname] path
|
|
58
|
+
#
|
|
59
|
+
# @return [Boolean]
|
|
60
|
+
def tracks?(path)
|
|
61
|
+
command = %W[git ls-files --error-unmatch -- #{path}]
|
|
62
|
+
config.kernel.system(
|
|
63
|
+
*command,
|
|
64
|
+
out: File::NULL,
|
|
65
|
+
err: File::NULL
|
|
66
|
+
)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Test if the path is within the current working directory
|
|
70
|
+
#
|
|
71
|
+
# @param [Pathname] path
|
|
72
|
+
#
|
|
73
|
+
# @return [TrueClass, nil]
|
|
74
|
+
def within_working_directory?(path)
|
|
75
|
+
working_directory = config.pathname.pwd
|
|
76
|
+
path.ascend { |parent| return true if working_directory.eql?(parent) }
|
|
77
|
+
end
|
|
78
|
+
end # Diff
|
|
79
|
+
end # Repository
|
|
80
|
+
end # Mutest
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
# Require highjack
|
|
3
|
+
module RequireHighjack
|
|
4
|
+
# Install require callback
|
|
5
|
+
#
|
|
6
|
+
# @param [Module] target
|
|
7
|
+
# @param [#call] callback
|
|
8
|
+
#
|
|
9
|
+
# @return [#call]
|
|
10
|
+
# the original implementation on singleton
|
|
11
|
+
def self.call(target, callback)
|
|
12
|
+
target.public_method(:require).tap do
|
|
13
|
+
target.module_eval do
|
|
14
|
+
undef_method(:require)
|
|
15
|
+
define_method(:require, &callback)
|
|
16
|
+
class << self
|
|
17
|
+
undef_method(:require)
|
|
18
|
+
end
|
|
19
|
+
define_singleton_method(:require, &callback)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end # RequireHighjack
|
|
24
|
+
end # Mutest
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
module Mutest
|
|
2
|
+
# Namespace and mixin module for results
|
|
3
|
+
module Result
|
|
4
|
+
# Coverage mixin
|
|
5
|
+
module Coverage
|
|
6
|
+
FULL_COVERAGE = Rational(1).freeze
|
|
7
|
+
private_constant(*constants(false))
|
|
8
|
+
|
|
9
|
+
# Observed coverage
|
|
10
|
+
#
|
|
11
|
+
# @return [Rational]
|
|
12
|
+
def coverage
|
|
13
|
+
if amount_mutation_results.zero?
|
|
14
|
+
FULL_COVERAGE
|
|
15
|
+
else
|
|
16
|
+
Rational(amount_mutations_killed, amount_mutation_results)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end # Coverage
|
|
20
|
+
|
|
21
|
+
# Class level mixin
|
|
22
|
+
module ClassMethods
|
|
23
|
+
# Generate a sum method from name and collection
|
|
24
|
+
#
|
|
25
|
+
# @param [Symbol] name
|
|
26
|
+
# the attribute name on collection item and method name to use
|
|
27
|
+
#
|
|
28
|
+
# @param [Symbol] collection
|
|
29
|
+
# the attribute name used to receive collection
|
|
30
|
+
#
|
|
31
|
+
# @return [undefined]
|
|
32
|
+
def sum(name, collection)
|
|
33
|
+
define_method(name) do
|
|
34
|
+
public_send(collection).map(&name).reduce(0, :+)
|
|
35
|
+
end
|
|
36
|
+
memoize(name)
|
|
37
|
+
end
|
|
38
|
+
end # ClassMethods
|
|
39
|
+
|
|
40
|
+
private_constant(*constants(false))
|
|
41
|
+
|
|
42
|
+
# Mutest overhead running mutatet tests
|
|
43
|
+
#
|
|
44
|
+
# This is NOT the overhead of mutation testing, just an engine specific
|
|
45
|
+
# measurement for the efficiency of the parallelization engine, kill
|
|
46
|
+
# isolation etc.
|
|
47
|
+
#
|
|
48
|
+
# @return [Float]
|
|
49
|
+
def overhead
|
|
50
|
+
runtime - killtime
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Hook called when module gets included
|
|
54
|
+
#
|
|
55
|
+
# @param [Class, Module] host
|
|
56
|
+
#
|
|
57
|
+
# @return [undefined]
|
|
58
|
+
def self.included(host)
|
|
59
|
+
host.class_eval do
|
|
60
|
+
include Adamantium
|
|
61
|
+
extend ClassMethods
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Env result object
|
|
66
|
+
class Env
|
|
67
|
+
include Coverage, Result, Anima.new(
|
|
68
|
+
:env,
|
|
69
|
+
:runtime,
|
|
70
|
+
:subject_results
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# Test if run is successful
|
|
74
|
+
#
|
|
75
|
+
# @return [Boolean]
|
|
76
|
+
def success?
|
|
77
|
+
coverage.eql?(Rational(1))
|
|
78
|
+
end
|
|
79
|
+
memoize :success?
|
|
80
|
+
|
|
81
|
+
# Failed subject results
|
|
82
|
+
#
|
|
83
|
+
# @return [Array<Result::Subject>]
|
|
84
|
+
def failed_subject_results
|
|
85
|
+
subject_results.reject(&:success?)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
sum :amount_mutation_results, :subject_results
|
|
89
|
+
sum :amount_mutations_alive, :subject_results
|
|
90
|
+
sum :amount_mutations_killed, :subject_results
|
|
91
|
+
sum :killtime, :subject_results
|
|
92
|
+
|
|
93
|
+
# Amount of mutations
|
|
94
|
+
#
|
|
95
|
+
# @return [Fixnum]
|
|
96
|
+
def amount_mutations
|
|
97
|
+
env.mutations.length
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Amount of subjects
|
|
101
|
+
#
|
|
102
|
+
# @return [Fixnum]
|
|
103
|
+
def amount_subjects
|
|
104
|
+
env.subjects.length
|
|
105
|
+
end
|
|
106
|
+
end # Env
|
|
107
|
+
|
|
108
|
+
# Test result
|
|
109
|
+
class Test
|
|
110
|
+
include Result, Anima.new(
|
|
111
|
+
:output,
|
|
112
|
+
:passed,
|
|
113
|
+
:runtime,
|
|
114
|
+
:tests
|
|
115
|
+
)
|
|
116
|
+
end # Test
|
|
117
|
+
|
|
118
|
+
# Subject result
|
|
119
|
+
class Subject
|
|
120
|
+
include Coverage, Result, Anima.new(
|
|
121
|
+
:mutation_results,
|
|
122
|
+
:subject,
|
|
123
|
+
:tests
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
sum :killtime, :mutation_results
|
|
127
|
+
sum :runtime, :mutation_results
|
|
128
|
+
|
|
129
|
+
# Test if subject was processed successful
|
|
130
|
+
#
|
|
131
|
+
# @return [Boolean]
|
|
132
|
+
def success?
|
|
133
|
+
alive_mutation_results.empty?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Alive mutations
|
|
137
|
+
#
|
|
138
|
+
# @return [Array<Result::Mutation>]
|
|
139
|
+
def alive_mutation_results
|
|
140
|
+
mutation_results.reject(&:success?)
|
|
141
|
+
end
|
|
142
|
+
memoize :alive_mutation_results
|
|
143
|
+
|
|
144
|
+
# Amount of mutations
|
|
145
|
+
#
|
|
146
|
+
# @return [Fixnum]
|
|
147
|
+
def amount_mutation_results
|
|
148
|
+
mutation_results.length
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Amount of mutations
|
|
152
|
+
#
|
|
153
|
+
# @return [Fixnum]
|
|
154
|
+
def amount_mutations
|
|
155
|
+
subject.mutations.length
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Number of killed mutations
|
|
159
|
+
#
|
|
160
|
+
# @return [Fixnum]
|
|
161
|
+
def amount_mutations_killed
|
|
162
|
+
killed_mutation_results.length
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Number of alive mutations
|
|
166
|
+
#
|
|
167
|
+
# @return [Fixnum]
|
|
168
|
+
def amount_mutations_alive
|
|
169
|
+
alive_mutation_results.length
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
private
|
|
173
|
+
|
|
174
|
+
# Killed mutation results
|
|
175
|
+
#
|
|
176
|
+
# @return [Array<Result::Mutation>]
|
|
177
|
+
def killed_mutation_results
|
|
178
|
+
mutation_results.select(&:success?)
|
|
179
|
+
end
|
|
180
|
+
memoize :killed_mutation_results
|
|
181
|
+
end # Subject
|
|
182
|
+
|
|
183
|
+
# Mutation result
|
|
184
|
+
class Mutation
|
|
185
|
+
include Result, Anima.new(
|
|
186
|
+
:mutation,
|
|
187
|
+
:test_result
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# The runtime
|
|
191
|
+
#
|
|
192
|
+
# @return [Float]
|
|
193
|
+
def runtime
|
|
194
|
+
test_result.runtime
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# The time spent on killing
|
|
198
|
+
#
|
|
199
|
+
# @return [Float]
|
|
200
|
+
#
|
|
201
|
+
# @api private
|
|
202
|
+
alias_method :killtime, :runtime
|
|
203
|
+
|
|
204
|
+
# Test if mutation was handled successfully
|
|
205
|
+
#
|
|
206
|
+
# @return [Boolean]
|
|
207
|
+
def success?
|
|
208
|
+
mutation.class.success?(test_result)
|
|
209
|
+
end
|
|
210
|
+
end # Mutation
|
|
211
|
+
end # Result
|
|
212
|
+
end # Mutest
|