mutant 0.8.10 → 0.8.11

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.
Files changed (247) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -4
  3. data/Changelog.md +8 -0
  4. data/README.md +112 -43
  5. data/Rakefile +2 -16
  6. data/circle.yml +1 -1
  7. data/config/flay.yml +2 -2
  8. data/config/flog.yml +1 -1
  9. data/config/reek.yml +3 -4
  10. data/config/rubocop.yml +53 -16
  11. data/lib/mutant.rb +27 -6
  12. data/lib/mutant/ast/meta/const.rb +2 -0
  13. data/lib/mutant/ast/meta/optarg.rb +2 -0
  14. data/lib/mutant/ast/meta/resbody.rb +2 -0
  15. data/lib/mutant/ast/meta/restarg.rb +2 -0
  16. data/lib/mutant/ast/meta/send.rb +4 -0
  17. data/lib/mutant/ast/meta/symbol.rb +2 -0
  18. data/lib/mutant/ast/named_children.rb +14 -4
  19. data/lib/mutant/ast/nodes.rb +3 -1
  20. data/lib/mutant/ast/regexp.rb +53 -0
  21. data/lib/mutant/ast/regexp/transformer.rb +185 -0
  22. data/lib/mutant/ast/regexp/transformer/alternative.rb +39 -0
  23. data/lib/mutant/ast/regexp/transformer/character_set.rb +46 -0
  24. data/lib/mutant/ast/regexp/transformer/direct.rb +99 -0
  25. data/lib/mutant/ast/regexp/transformer/options_group.rb +66 -0
  26. data/lib/mutant/ast/regexp/transformer/quantifier.rb +112 -0
  27. data/lib/mutant/ast/regexp/transformer/recursive.rb +50 -0
  28. data/lib/mutant/ast/regexp/transformer/root.rb +29 -0
  29. data/lib/mutant/ast/regexp/transformer/text.rb +55 -0
  30. data/lib/mutant/ast/types.rb +92 -5
  31. data/lib/mutant/cli.rb +2 -14
  32. data/lib/mutant/color.rb +1 -1
  33. data/lib/mutant/config.rb +1 -3
  34. data/lib/mutant/expression/methods.rb +1 -1
  35. data/lib/mutant/expression/namespace.rb +2 -2
  36. data/lib/mutant/expression/parser.rb +1 -1
  37. data/lib/mutant/integration.rb +10 -28
  38. data/lib/mutant/isolation.rb +9 -60
  39. data/lib/mutant/isolation/fork.rb +72 -0
  40. data/lib/mutant/isolation/none.rb +25 -0
  41. data/lib/mutant/matcher/config.rb +2 -0
  42. data/lib/mutant/matcher/method/singleton.rb +5 -4
  43. data/lib/mutant/meta.rb +11 -4
  44. data/lib/mutant/meta/example.rb +2 -116
  45. data/lib/mutant/meta/example/dsl.rb +22 -19
  46. data/lib/mutant/meta/example/verification.rb +86 -0
  47. data/lib/mutant/mutator.rb +22 -49
  48. data/lib/mutant/mutator/node.rb +15 -19
  49. data/lib/mutant/mutator/node/and_asgn.rb +1 -1
  50. data/lib/mutant/mutator/node/argument.rb +10 -5
  51. data/lib/mutant/mutator/node/arguments.rb +5 -9
  52. data/lib/mutant/mutator/node/begin.rb +4 -17
  53. data/lib/mutant/mutator/node/block.rb +1 -1
  54. data/lib/mutant/mutator/node/break.rb +1 -1
  55. data/lib/mutant/mutator/node/class.rb +21 -0
  56. data/lib/mutant/mutator/node/conditional_loop.rb +1 -1
  57. data/lib/mutant/mutator/node/define.rb +1 -1
  58. data/lib/mutant/mutator/node/defined.rb +1 -1
  59. data/lib/mutant/mutator/node/dstr.rb +1 -1
  60. data/lib/mutant/mutator/node/dsym.rb +1 -1
  61. data/lib/mutant/mutator/node/generic.rb +3 -3
  62. data/lib/mutant/mutator/node/kwbegin.rb +1 -1
  63. data/lib/mutant/mutator/node/literal.rb +9 -0
  64. data/lib/mutant/mutator/node/literal/boolean.rb +1 -1
  65. data/lib/mutant/mutator/node/literal/fixnum.rb +2 -2
  66. data/lib/mutant/mutator/node/literal/float.rb +4 -6
  67. data/lib/mutant/mutator/node/literal/hash.rb +1 -1
  68. data/lib/mutant/mutator/node/literal/nil.rb +1 -1
  69. data/lib/mutant/mutator/node/literal/range.rb +2 -19
  70. data/lib/mutant/mutator/node/literal/regex.rb +43 -3
  71. data/lib/mutant/mutator/node/literal/string.rb +1 -1
  72. data/lib/mutant/mutator/node/literal/symbol.rb +2 -4
  73. data/lib/mutant/mutator/node/masgn.rb +1 -1
  74. data/lib/mutant/mutator/node/match_current_line.rb +1 -1
  75. data/lib/mutant/mutator/node/mlhs.rb +2 -3
  76. data/lib/mutant/mutator/node/named_value/access.rb +2 -2
  77. data/lib/mutant/mutator/node/named_value/constant_assignment.rb +4 -3
  78. data/lib/mutant/mutator/node/named_value/variable_assignment.rb +4 -4
  79. data/lib/mutant/mutator/node/next.rb +1 -1
  80. data/lib/mutant/mutator/node/nthref.rb +1 -1
  81. data/lib/mutant/mutator/node/or_asgn.rb +1 -1
  82. data/lib/mutant/mutator/node/regexp.rb +44 -0
  83. data/lib/mutant/mutator/node/regopt.rb +31 -0
  84. data/lib/mutant/mutator/node/resbody.rb +1 -1
  85. data/lib/mutant/mutator/node/rescue.rb +1 -3
  86. data/lib/mutant/mutator/node/return.rb +1 -1
  87. data/lib/mutant/mutator/node/send.rb +43 -3
  88. data/lib/mutant/mutator/node/send/attribute_assignment.rb +4 -1
  89. data/lib/mutant/mutator/node/send/conditional.rb +23 -0
  90. data/lib/mutant/mutator/node/send/index.rb +1 -1
  91. data/lib/mutant/mutator/node/splat.rb +1 -1
  92. data/lib/mutant/mutator/node/when.rb +1 -1
  93. data/lib/mutant/mutator/node/yield.rb +1 -1
  94. data/lib/mutant/mutator/util.rb +0 -30
  95. data/lib/mutant/mutator/util/array.rb +4 -16
  96. data/lib/mutant/parallel.rb +1 -1
  97. data/lib/mutant/parallel/worker.rb +1 -1
  98. data/lib/mutant/registry.rb +44 -0
  99. data/lib/mutant/reporter/cli/format.rb +2 -0
  100. data/lib/mutant/reporter/cli/printer.rb +2 -2
  101. data/lib/mutant/reporter/cli/printer/config.rb +0 -1
  102. data/lib/mutant/reporter/cli/printer/env_progress.rb +1 -11
  103. data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +1 -1
  104. data/lib/mutant/reporter/cli/printer/mutation_result.rb +2 -0
  105. data/lib/mutant/reporter/cli/tput.rb +1 -1
  106. data/lib/mutant/reporter/sequence.rb +3 -0
  107. data/lib/mutant/require_highjack.rb +6 -2
  108. data/lib/mutant/result.rb +1 -1
  109. data/lib/mutant/subject.rb +5 -5
  110. data/lib/mutant/subject/method/instance.rb +1 -2
  111. data/lib/mutant/util.rb +18 -0
  112. data/lib/mutant/version.rb +1 -1
  113. data/lib/mutant/zombifier.rb +5 -3
  114. data/meta/and.rb +1 -1
  115. data/meta/and_asgn.rb +1 -1
  116. data/meta/array.rb +2 -2
  117. data/meta/begin.rb +2 -2
  118. data/meta/block.rb +7 -7
  119. data/meta/block_pass.rb +1 -1
  120. data/meta/blockarg.rb +1 -1
  121. data/meta/break.rb +1 -1
  122. data/meta/case.rb +2 -2
  123. data/meta/casgn.rb +11 -2
  124. data/meta/cbase.rb +1 -1
  125. data/meta/class.rb +10 -0
  126. data/meta/const.rb +9 -1
  127. data/meta/csend.rb +8 -0
  128. data/meta/cvar.rb +1 -1
  129. data/meta/cvasgn.rb +1 -1
  130. data/meta/date.rb +4 -4
  131. data/meta/def.rb +14 -14
  132. data/meta/defined.rb +1 -1
  133. data/meta/dstr.rb +1 -1
  134. data/meta/dsym.rb +1 -1
  135. data/meta/ensure.rb +1 -1
  136. data/meta/false.rb +1 -1
  137. data/meta/float.rb +3 -3
  138. data/meta/gvar.rb +1 -1
  139. data/meta/gvasgn.rb +1 -1
  140. data/meta/hash.rb +1 -1
  141. data/meta/if.rb +17 -3
  142. data/meta/int.rb +1 -1
  143. data/meta/ivar.rb +1 -1
  144. data/meta/ivasgn.rb +14 -1
  145. data/meta/kwarg.rb +8 -0
  146. data/meta/kwbegin.rb +1 -1
  147. data/meta/kwoptarg.rb +11 -0
  148. data/meta/lvar.rb +1 -1
  149. data/meta/lvasgn.rb +1 -1
  150. data/meta/masgn.rb +1 -1
  151. data/meta/match_current_line.rb +2 -2
  152. data/meta/next.rb +1 -1
  153. data/meta/nil.rb +1 -1
  154. data/meta/nthref.rb +5 -5
  155. data/meta/op_assgn.rb +1 -1
  156. data/meta/or.rb +1 -1
  157. data/meta/or_asgn.rb +5 -5
  158. data/meta/range.rb +2 -8
  159. data/meta/redo.rb +1 -1
  160. data/meta/regexp.rb +106 -0
  161. data/meta/regexp/regexp_bol_anchor.rb +13 -0
  162. data/meta/regexp/regexp_bos_anchor.rb +26 -0
  163. data/meta/regexp/regexp_root_expression.rb +13 -0
  164. data/meta/regopt.rb +8 -0
  165. data/meta/rescue.rb +49 -4
  166. data/meta/restarg.rb +6 -9
  167. data/meta/return.rb +2 -2
  168. data/meta/self.rb +1 -1
  169. data/meta/send.rb +228 -55
  170. data/meta/str.rb +1 -1
  171. data/meta/super.rb +3 -3
  172. data/meta/{symbol.rb → sym.rb} +1 -1
  173. data/meta/true.rb +1 -1
  174. data/meta/until.rb +1 -1
  175. data/meta/while.rb +2 -2
  176. data/meta/yield.rb +1 -1
  177. data/mutant-rspec.gemspec +2 -2
  178. data/mutant.gemspec +6 -5
  179. data/spec/integration/mutant/isolation/fork_spec.rb +8 -0
  180. data/spec/integration/mutant/rspec_spec.rb +1 -1
  181. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +1 -2
  182. data/spec/integrations.yml +93 -24
  183. data/spec/spec_helper.rb +12 -7
  184. data/spec/support/compress_helper.rb +1 -1
  185. data/spec/support/corpus.rb +115 -50
  186. data/spec/support/fake_actor.rb +5 -5
  187. data/spec/support/file_system.rb +1 -1
  188. data/spec/support/ice_nine_config.rb +3 -3
  189. data/spec/support/ruby_vm.rb +11 -12
  190. data/spec/support/shared_context.rb +22 -13
  191. data/spec/support/test_app.rb +1 -1
  192. data/spec/support/warning.rb +64 -0
  193. data/spec/support/warnings.yml +4 -0
  194. data/spec/support/xspec.rb +177 -0
  195. data/spec/unit/mutant/actor/env_spec.rb +2 -2
  196. data/spec/unit/mutant/actor/sender_spec.rb +1 -1
  197. data/spec/unit/mutant/ast/meta/send_spec.rb +1 -1
  198. data/spec/unit/mutant/ast/named_children_spec.rb +26 -0
  199. data/spec/unit/mutant/ast/regexp/parse_spec.rb +7 -0
  200. data/spec/unit/mutant/ast/regexp/supported_predicate_spec.rb +14 -0
  201. data/spec/unit/mutant/ast/regexp/transformer/lookup_table/table_spec.rb +19 -0
  202. data/spec/unit/mutant/ast/regexp/transformer/lookup_table_spec.rb +33 -0
  203. data/spec/unit/mutant/ast/regexp/transformer_spec.rb +19 -0
  204. data/spec/unit/mutant/ast/regexp_spec.rb +617 -0
  205. data/spec/unit/mutant/cli_spec.rb +7 -45
  206. data/spec/unit/mutant/context_spec.rb +4 -7
  207. data/spec/unit/mutant/env/{boostrap_spec.rb → bootstrap_spec.rb} +2 -2
  208. data/spec/unit/mutant/env_spec.rb +13 -16
  209. data/spec/unit/mutant/expression/namespace/{flat_spec.rb → exact_spec.rb} +0 -0
  210. data/spec/unit/mutant/integration/rspec_spec.rb +2 -2
  211. data/spec/unit/mutant/integration_spec.rb +14 -0
  212. data/spec/unit/mutant/isolation/fork_spec.rb +155 -0
  213. data/spec/unit/mutant/isolation/none_spec.rb +16 -0
  214. data/spec/unit/mutant/loader_spec.rb +1 -1
  215. data/spec/unit/mutant/matcher/methods/instance_spec.rb +2 -4
  216. data/spec/unit/mutant/meta/example/dsl_spec.rb +106 -0
  217. data/spec/unit/mutant/meta/example/verification_spec.rb +120 -0
  218. data/spec/unit/mutant/meta/example_spec.rb +32 -0
  219. data/spec/unit/mutant/mutator/node_spec.rb +37 -4
  220. data/spec/unit/mutant/mutator_spec.rb +21 -0
  221. data/spec/unit/mutant/{runner → parallel}/driver_spec.rb +0 -0
  222. data/spec/unit/mutant/parallel/master_spec.rb +13 -13
  223. data/spec/unit/mutant/registry_spec.rb +47 -0
  224. data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +0 -4
  225. data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +0 -8
  226. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +0 -2
  227. data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +0 -8
  228. data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +0 -34
  229. data/spec/unit/mutant/reporter/cli_spec.rb +0 -22
  230. data/spec/unit/mutant/repository/diff_spec.rb +6 -6
  231. data/spec/unit/mutant/require_highjack_spec.rb +38 -14
  232. data/spec/unit/mutant/result/env_spec.rb +1 -4
  233. data/spec/unit/mutant/runner_spec.rb +1 -1
  234. data/spec/unit/mutant/subject/method/instance_spec.rb +1 -1
  235. data/spec/unit/mutant/subject_spec.rb +3 -3
  236. data/spec/unit/mutant/util/one_spec.rb +20 -0
  237. data/spec/unit/mutant/zombifier_spec.rb +18 -18
  238. data/test_app/{Gemfile.rspec3.3 → Gemfile.rspec3.5} +2 -2
  239. metadata +94 -24
  240. data/TODO +0 -21
  241. data/lib/mutant/mutator/node/blockarg.rb +0 -13
  242. data/lib/mutant/mutator/node/restarg.rb +0 -13
  243. data/lib/mutant/mutator/registry.rb +0 -49
  244. data/meta/boolean.rb +0 -13
  245. data/meta/regex.rb +0 -19
  246. data/spec/unit/mutant/isolation_spec.rb +0 -104
  247. data/spec/unit/mutant/mutator/registry_spec.rb +0 -57
data/TODO DELETED
@@ -1,21 +0,0 @@
1
- Code:
2
- * Test mutant with dynamically created zombie.
3
-
4
- Mutations:
5
- * Add true masgn mutations
6
- * Add some kind of a "do not touch me object" that raises on all messages.
7
- It can be used to make sure each literal value is touched.
8
- * Replace nil or add "do not touch me object" to literal mutations.
9
- * Mutate options on Regexp literals
10
- * Add mutations for dynamic regexp symbol and string literals
11
- * Add timeout to terminate infinite loops
12
-
13
- Loader:
14
- * Make sure loader does not change visibility of injected mutants
15
-
16
- Matcher:
17
- * Allow matches on attr_reader with literal name argument(s)?
18
- * Allow matches on define_method with literal name argument?
19
-
20
- jruby-support:
21
- * Create a runtime per mutation to kill mutations in isolation
@@ -1,13 +0,0 @@
1
- module Mutant
2
- class Mutator
3
- class Node
4
-
5
- # Blockarg mutator
6
- class Blockarg < Generic
7
-
8
- handle(:blockarg)
9
-
10
- end # Blockarg
11
- end # Node
12
- end # Mutator
13
- end # Mutant
@@ -1,13 +0,0 @@
1
- module Mutant
2
- class Mutator
3
- class Node
4
-
5
- # Restarg mutator
6
- class Restarg < Generic
7
-
8
- handle(:restarg)
9
-
10
- end # Restarg
11
- end # Node
12
- end # Mutator
13
- end # Mutant
@@ -1,49 +0,0 @@
1
- module Mutant
2
- class Mutator
3
- # Registry for mutators
4
- class Registry
5
-
6
- # Initialize object
7
- #
8
- # @return [undefined]
9
- def initialize
10
- @registry = {}
11
- end
12
-
13
- # Raised when the type is an invalid type
14
- RegistryError = Class.new(TypeError)
15
-
16
- # Register mutator class for AST node class
17
- #
18
- # @param [Symbol] type
19
- # @param [Class:Mutator] mutator
20
- #
21
- # @return [self]
22
- def register(type, mutator)
23
- fail RegistryError, "Invalid type registration: #{type}" unless AST::Types::ALL.include?(type)
24
- fail RegistryError, "Duplicate type registration: #{type}" if @registry.key?(type)
25
- @registry[type] = mutator
26
- self
27
- end
28
-
29
- # Lookup mutator class for node
30
- #
31
- # @param [Parser::AST::Node] node
32
- #
33
- # @return [Class]
34
- #
35
- # @raise [ArgumentError]
36
- # raises argument error when mutator class cannot be found
37
- def lookup(node)
38
- type = node.type
39
- @registry.fetch(type) do
40
- fail RegistryError, "No mutator to handle: #{type.inspect}"
41
- end
42
- end
43
-
44
- end # Registry
45
-
46
- REGISTRY = Registry.new
47
-
48
- end # Mutator
49
- end # Mutant
@@ -1,13 +0,0 @@
1
- Mutant::Meta::Example.add do
2
- source 'true'
3
-
4
- mutation 'nil'
5
- mutation 'false'
6
- end
7
-
8
- Mutant::Meta::Example.add do
9
- source 'false'
10
-
11
- mutation 'nil'
12
- mutation 'true'
13
- end
@@ -1,19 +0,0 @@
1
- Mutant::Meta::Example.add do
2
- source '/foo/'
3
-
4
- singleton_mutations
5
- mutation '//' # match all
6
- mutation '/a\A/' # match nothing
7
- end
8
-
9
- Mutant::Meta::Example.add do
10
- source '/#{foo.bar}n/'
11
-
12
- singleton_mutations
13
- mutation '//' # match all
14
- mutation '/#{foo}n/'
15
- mutation '/a\A/' # match nothing
16
- mutation '/#{self.bar}n/'
17
- mutation '/#{nil}n/'
18
- mutation '/#{self}n/'
19
- end
@@ -1,104 +0,0 @@
1
- RSpec.describe Mutant::Isolation::None do
2
- before do
3
- @initial = 1
4
- end
5
-
6
- describe '.run' do
7
- let(:object) { described_class }
8
-
9
- it 'does not isolate side effects' do
10
- object.call { @initial = 2 }
11
- expect(@initial).to be(2)
12
- end
13
-
14
- it 'return block value' do
15
- expect(object.call { :foo }).to be(:foo)
16
- end
17
-
18
- it 'wraps *all* exceptions' do
19
- expect { object.call { fail } }.to raise_error(Mutant::Isolation::Error)
20
- end
21
-
22
- end
23
- end
24
-
25
- RSpec.describe Mutant::Isolation::Fork do
26
- before do
27
- @initial = 1
28
- end
29
-
30
- describe '.run' do
31
- let(:object) { described_class }
32
-
33
- it 'does isolate side effects' do
34
- object.call { @initial = 2 }
35
- expect(@initial).to be(1)
36
- end
37
-
38
- it 'return block value' do
39
- expect(object.call { :foo }).to be(:foo)
40
- end
41
-
42
- it 'wraps exceptions' do
43
- expect { object.call { fail } }.to raise_error(Mutant::Isolation::Error, 'marshal data too short')
44
- end
45
-
46
- it 'wraps exceptions caused by crashing ruby' do
47
- expect do
48
- object.call do
49
- fail RbBug.call
50
- end
51
- end.to raise_error(Mutant::Isolation::Error)
52
- end
53
-
54
- it 'redirects $stderr of children to /dev/null' do
55
- begin
56
- Tempfile.open('mutant-test') do |file|
57
- $stderr = file
58
- object.call { $stderr.puts('test') }
59
- file.rewind
60
- expect(file.read).to eql('')
61
- end
62
- ensure
63
- $stderr = STDERR
64
- end
65
- end
66
-
67
- context 'uses primitives in correct order' do
68
- let(:reader) { instance_double(IO) }
69
- let(:writer) { instance_double(IO) }
70
-
71
- before do
72
- expect(IO).to receive(:pipe).with(binmode: true).ordered do |&block|
73
- block.call([reader, writer])
74
- end
75
- expect(writer).to receive(:binmode).ordered
76
- end
77
-
78
- it 'when fork succeeds' do
79
- pid = instance_double(Fixnum)
80
- expect(Process).to receive(:fork).ordered.and_yield.and_return(pid)
81
- file = instance_double(File)
82
- expect(File).to receive(:open).ordered
83
- .with(File::NULL, File::WRONLY).and_yield(file)
84
- expect($stderr).to receive(:reopen).ordered.with(file)
85
- expect(reader).to receive(:close).ordered
86
- expect(writer).to receive(:write).ordered.with(Marshal.dump(:foo))
87
- expect(writer).to receive(:close).ordered
88
- expect(writer).to receive(:close).ordered
89
- expect(reader).to receive(:read).ordered.and_return(Marshal.dump(:foo))
90
- expect(Process).to receive(:waitpid).with(pid)
91
-
92
- expect(object.call { :foo }).to be(:foo)
93
- end
94
-
95
- it 'when fork fails' do
96
- expect(Process).to receive(:fork).ordered.and_return(nil)
97
- expect(Process).to_not receive(:waitpid)
98
- expect(writer).to receive(:close).ordered
99
- expect(reader).to receive(:read).ordered.and_return(Marshal.dump(:foo))
100
- expect(object.call).to be(:foo)
101
- end
102
- end
103
- end
104
- end
@@ -1,57 +0,0 @@
1
- RSpec.describe Mutant::Mutator::Registry do
2
- describe '#lookup' do
3
- subject { Mutant::Mutator::REGISTRY.lookup(node) }
4
-
5
- context 'on registered node' do
6
- let(:node) { s(:true) }
7
-
8
- it { should eql(Mutant::Mutator::Node::Literal::Boolean) }
9
- end
10
-
11
- context 'on unknown node' do
12
- let(:node) { s(:unknown) }
13
-
14
- it 'raises error' do
15
- expect { subject }.to raise_error(described_class::RegistryError, 'No mutator to handle: :unknown')
16
- end
17
- end
18
- end
19
-
20
- describe '#register' do
21
- let(:object) { described_class.new }
22
-
23
- let(:mutator) { instance_double(Mutant::Mutator) }
24
-
25
- subject { object.register(type, mutator) }
26
-
27
- context 'when registering an invalid node type' do
28
- let(:type) { :invalid }
29
-
30
- it 'raises error' do
31
- expect { subject }.to raise_error(described_class::RegistryError, 'Invalid type registration: invalid')
32
- end
33
- end
34
-
35
- context 'when registering a valid node type' do
36
- let(:type) { :true }
37
-
38
- it 'allows to lookup mutator' do
39
- subject
40
- expect(object.lookup(s(type))).to be(mutator)
41
- end
42
-
43
- it_behaves_like 'a command method'
44
- end
45
-
46
- context 'when duplicate the registration of a valid node type' do
47
- let(:type) { :true }
48
-
49
- it 'allows to lookup mutator' do
50
- object.register(type, mutator)
51
- expect { subject }.to raise_error(described_class::RegistryError, 'Duplicate type registration: true')
52
- end
53
-
54
- it_behaves_like 'a command method'
55
- end
56
- end
57
- end