mutant 0.9.9 → 0.9.14

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 (252) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mutant.rb +2 -4
  3. data/lib/mutant/bootstrap.rb +14 -1
  4. data/lib/mutant/cli.rb +6 -0
  5. data/lib/mutant/isolation.rb +1 -1
  6. data/lib/mutant/isolation/fork.rb +2 -2
  7. data/lib/mutant/isolation/none.rb +1 -1
  8. data/lib/mutant/matcher/config.rb +2 -0
  9. data/lib/mutant/meta/example.rb +16 -4
  10. data/lib/mutant/meta/example/dsl.rb +33 -16
  11. data/lib/mutant/meta/example/verification.rb +70 -28
  12. data/lib/mutant/minitest/coverage.rb +53 -0
  13. data/lib/mutant/mutator/node.rb +2 -2
  14. data/lib/mutant/mutator/node/block_pass.rb +29 -0
  15. data/lib/mutant/mutator/node/{dstr.rb → dynamic_literal.rb} +7 -5
  16. data/lib/mutant/mutator/node/index.rb +4 -4
  17. data/lib/mutant/mutator/node/literal/range.rb +4 -1
  18. data/lib/mutant/mutator/node/noop.rb +1 -1
  19. data/lib/mutant/mutator/node/op_asgn.rb +15 -1
  20. data/lib/mutant/mutator/node/send.rb +25 -1
  21. data/lib/mutant/mutator/node/send/attribute_assignment.rb +1 -0
  22. data/lib/mutant/reporter/cli/printer.rb +2 -2
  23. data/lib/mutant/reporter/cli/printer/isolation_result.rb +9 -3
  24. data/lib/mutant/reporter/cli/printer/mutation_result.rb +1 -1
  25. data/lib/mutant/subject/method/instance.rb +41 -2
  26. data/lib/mutant/version.rb +1 -1
  27. metadata +59 -347
  28. data/.github/workflows/ci.yml +0 -121
  29. data/.gitignore +0 -38
  30. data/.rspec +0 -5
  31. data/.rubocop.yml +0 -7
  32. data/Changelog.md +0 -81
  33. data/Gemfile +0 -7
  34. data/Gemfile.lock +0 -167
  35. data/Gemfile.shared +0 -10
  36. data/README.md +0 -178
  37. data/Rakefile +0 -5
  38. data/config/devtools.yml +0 -2
  39. data/config/reek.yml +0 -139
  40. data/config/rubocop.yml +0 -205
  41. data/config/yardstick.yml +0 -2
  42. data/docs/commercial-support.md +0 -14
  43. data/docs/concurrency.md +0 -39
  44. data/docs/incremental.md +0 -76
  45. data/docs/known-problems.md +0 -30
  46. data/docs/limitations.md +0 -50
  47. data/docs/mutant-minitest.md +0 -149
  48. data/docs/mutant-rspec.md +0 -130
  49. data/docs/nomenclature.md +0 -82
  50. data/docs/reading-reports.md +0 -74
  51. data/lib/mutant/color.rb +0 -40
  52. data/lib/mutant/diff.rb +0 -97
  53. data/lib/mutant/mutator/node/dsym.rb +0 -22
  54. data/meta/and.rb +0 -13
  55. data/meta/and_asgn.rb +0 -14
  56. data/meta/array.rb +0 -27
  57. data/meta/begin.rb +0 -20
  58. data/meta/block.rb +0 -199
  59. data/meta/block_pass.rb +0 -8
  60. data/meta/blockarg.rb +0 -10
  61. data/meta/break.rb +0 -9
  62. data/meta/case.rb +0 -217
  63. data/meta/casgn.rb +0 -25
  64. data/meta/cbase.rb +0 -8
  65. data/meta/class.rb +0 -12
  66. data/meta/const.rb +0 -17
  67. data/meta/csend.rb +0 -10
  68. data/meta/cvar.rb +0 -7
  69. data/meta/cvasgn.rb +0 -9
  70. data/meta/date.rb +0 -59
  71. data/meta/def.rb +0 -196
  72. data/meta/defined.rb +0 -9
  73. data/meta/dstr.rb +0 -13
  74. data/meta/dsym.rb +0 -14
  75. data/meta/ensure.rb +0 -8
  76. data/meta/false.rb +0 -7
  77. data/meta/file.rb +0 -5
  78. data/meta/float.rb +0 -37
  79. data/meta/gvar.rb +0 -7
  80. data/meta/gvasgn.rb +0 -9
  81. data/meta/hash.rb +0 -20
  82. data/meta/if.rb +0 -72
  83. data/meta/index.rb +0 -133
  84. data/meta/indexasgn.rb +0 -31
  85. data/meta/int.rb +0 -18
  86. data/meta/ivar.rb +0 -8
  87. data/meta/ivasgn.rb +0 -22
  88. data/meta/kwarg.rb +0 -10
  89. data/meta/kwbegin.rb +0 -8
  90. data/meta/kwoptarg.rb +0 -13
  91. data/meta/lambda.rb +0 -23
  92. data/meta/line.rb +0 -5
  93. data/meta/lvar.rb +0 -16
  94. data/meta/lvasgn.rb +0 -24
  95. data/meta/masgn.rb +0 -7
  96. data/meta/match_current_line.rb +0 -14
  97. data/meta/next.rb +0 -10
  98. data/meta/nil.rb +0 -5
  99. data/meta/nthref.rb +0 -14
  100. data/meta/op_assgn.rb +0 -17
  101. data/meta/or.rb +0 -13
  102. data/meta/or_asgn.rb +0 -50
  103. data/meta/range.rb +0 -39
  104. data/meta/redo.rb +0 -5
  105. data/meta/regexp.rb +0 -80
  106. data/meta/regopt.rb +0 -10
  107. data/meta/rescue.rb +0 -84
  108. data/meta/return.rb +0 -16
  109. data/meta/sclass.rb +0 -12
  110. data/meta/self.rb +0 -7
  111. data/meta/send.rb +0 -600
  112. data/meta/str.rb +0 -7
  113. data/meta/super.rb +0 -27
  114. data/meta/sym.rb +0 -8
  115. data/meta/true.rb +0 -7
  116. data/meta/until.rb +0 -16
  117. data/meta/while.rb +0 -24
  118. data/meta/yield.rb +0 -9
  119. data/mutant-minitest.gemspec +0 -22
  120. data/mutant-rspec.gemspec +0 -22
  121. data/mutant.gemspec +0 -41
  122. data/mutant.sh +0 -12
  123. data/mutant.yml +0 -6
  124. data/spec/integration/mutant/corpus_spec.rb +0 -15
  125. data/spec/integration/mutant/isolation/fork_spec.rb +0 -28
  126. data/spec/integration/mutant/minitest_spec.rb +0 -11
  127. data/spec/integration/mutant/null_spec.rb +0 -16
  128. data/spec/integration/mutant/rspec_spec.rb +0 -15
  129. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +0 -9
  130. data/spec/integrations.yml +0 -63
  131. data/spec/shared/base_behavior.rb +0 -45
  132. data/spec/shared/framework_integration_behavior.rb +0 -70
  133. data/spec/shared/method_matcher_behavior.rb +0 -47
  134. data/spec/spec_helper.rb +0 -75
  135. data/spec/support/corpus.rb +0 -318
  136. data/spec/support/file_system.rb +0 -62
  137. data/spec/support/ice_nine_config.rb +0 -10
  138. data/spec/support/ruby_vm.rb +0 -84
  139. data/spec/support/shared_context.rb +0 -169
  140. data/spec/support/test_app.rb +0 -7
  141. data/spec/support/warnings.yml +0 -6
  142. data/spec/support/xspec.rb +0 -183
  143. data/spec/unit/mutant/ast/find_metaclass_containing_spec.rb +0 -64
  144. data/spec/unit/mutant/ast/meta/optarg_spec.rb +0 -24
  145. data/spec/unit/mutant/ast/meta/send/proc_predicate_spec.rb +0 -30
  146. data/spec/unit/mutant/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb +0 -39
  147. data/spec/unit/mutant/ast/meta/send_spec.rb +0 -42
  148. data/spec/unit/mutant/ast/named_children_spec.rb +0 -89
  149. data/spec/unit/mutant/ast/sexp_spec.rb +0 -38
  150. data/spec/unit/mutant/ast_spec.rb +0 -57
  151. data/spec/unit/mutant/bootstrap_spec.rb +0 -216
  152. data/spec/unit/mutant/cli_spec.rb +0 -305
  153. data/spec/unit/mutant/clock_monotonic_spec.rb +0 -52
  154. data/spec/unit/mutant/config_spec.rb +0 -126
  155. data/spec/unit/mutant/context_spec.rb +0 -111
  156. data/spec/unit/mutant/diff_spec.rb +0 -189
  157. data/spec/unit/mutant/env_spec.rb +0 -229
  158. data/spec/unit/mutant/expression/method_spec.rb +0 -62
  159. data/spec/unit/mutant/expression/methods_spec.rb +0 -66
  160. data/spec/unit/mutant/expression/namespace/exact_spec.rb +0 -28
  161. data/spec/unit/mutant/expression/namespace/recursive_spec.rb +0 -66
  162. data/spec/unit/mutant/expression/parser_spec.rb +0 -65
  163. data/spec/unit/mutant/expression_spec.rb +0 -45
  164. data/spec/unit/mutant/integration/rspec_spec.rb +0 -201
  165. data/spec/unit/mutant/integration_spec.rb +0 -150
  166. data/spec/unit/mutant/isolation/fork_spec.rb +0 -309
  167. data/spec/unit/mutant/isolation/none_spec.rb +0 -23
  168. data/spec/unit/mutant/isolation/result_spec.rb +0 -73
  169. data/spec/unit/mutant/license_spec.rb +0 -305
  170. data/spec/unit/mutant/loader_spec.rb +0 -79
  171. data/spec/unit/mutant/matcher/chain_spec.rb +0 -26
  172. data/spec/unit/mutant/matcher/compiler_spec.rb +0 -0
  173. data/spec/unit/mutant/matcher/config_spec.rb +0 -47
  174. data/spec/unit/mutant/matcher/filter_spec.rb +0 -22
  175. data/spec/unit/mutant/matcher/method/instance_spec.rb +0 -164
  176. data/spec/unit/mutant/matcher/method/metaclass_spec.rb +0 -108
  177. data/spec/unit/mutant/matcher/method/singleton_spec.rb +0 -90
  178. data/spec/unit/mutant/matcher/methods/instance_spec.rb +0 -54
  179. data/spec/unit/mutant/matcher/methods/metaclass_spec.rb +0 -62
  180. data/spec/unit/mutant/matcher/methods/singleton_spec.rb +0 -51
  181. data/spec/unit/mutant/matcher/namespace_spec.rb +0 -39
  182. data/spec/unit/mutant/matcher/null_spec.rb +0 -12
  183. data/spec/unit/mutant/matcher/scope_spec.rb +0 -45
  184. data/spec/unit/mutant/matcher/static_spec.rb +0 -13
  185. data/spec/unit/mutant/matcher_spec.rb +0 -102
  186. data/spec/unit/mutant/meta/example/dsl_spec.rb +0 -108
  187. data/spec/unit/mutant/meta/example/verification_spec.rb +0 -154
  188. data/spec/unit/mutant/meta/example_spec.rb +0 -34
  189. data/spec/unit/mutant/mutation_spec.rb +0 -140
  190. data/spec/unit/mutant/mutator/node_spec.rb +0 -47
  191. data/spec/unit/mutant/mutator_spec.rb +0 -21
  192. data/spec/unit/mutant/parallel/driver_spec.rb +0 -126
  193. data/spec/unit/mutant/parallel/source/array_spec.rb +0 -57
  194. data/spec/unit/mutant/parallel/worker_spec.rb +0 -206
  195. data/spec/unit/mutant/parallel_spec.rb +0 -115
  196. data/spec/unit/mutant/parser_spec.rb +0 -26
  197. data/spec/unit/mutant/range_spec.rb +0 -141
  198. data/spec/unit/mutant/registry_spec.rb +0 -74
  199. data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +0 -17
  200. data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +0 -85
  201. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +0 -45
  202. data/spec/unit/mutant/reporter/cli/printer/isolation_result_spec.rb +0 -132
  203. data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +0 -25
  204. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +0 -153
  205. data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +0 -45
  206. data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +0 -36
  207. data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +0 -44
  208. data/spec/unit/mutant/reporter/cli/printer/test_result_spec.rb +0 -16
  209. data/spec/unit/mutant/reporter/cli/printer_spec.rb +0 -163
  210. data/spec/unit/mutant/reporter/cli_spec.rb +0 -137
  211. data/spec/unit/mutant/reporter/null_spec.rb +0 -14
  212. data/spec/unit/mutant/reporter/sequence_spec.rb +0 -31
  213. data/spec/unit/mutant/repository/diff/ranges_spec.rb +0 -180
  214. data/spec/unit/mutant/repository/diff_spec.rb +0 -122
  215. data/spec/unit/mutant/repository/subject_filter_spec.rb +0 -30
  216. data/spec/unit/mutant/require_highjack_spec.rb +0 -73
  217. data/spec/unit/mutant/result/class_methods_spec.rb +0 -51
  218. data/spec/unit/mutant/result/env_spec.rb +0 -161
  219. data/spec/unit/mutant/result/mutation_spec.rb +0 -70
  220. data/spec/unit/mutant/result/subject_spec.rb +0 -111
  221. data/spec/unit/mutant/result/test_spec.rb +0 -14
  222. data/spec/unit/mutant/result_spec.rb +0 -33
  223. data/spec/unit/mutant/runner/sink_spec.rb +0 -174
  224. data/spec/unit/mutant/runner_spec.rb +0 -121
  225. data/spec/unit/mutant/selector/expression_spec.rb +0 -62
  226. data/spec/unit/mutant/selector/null_spec.rb +0 -17
  227. data/spec/unit/mutant/subject/method/instance_spec.rb +0 -181
  228. data/spec/unit/mutant/subject/method/metaclass_spec.rb +0 -63
  229. data/spec/unit/mutant/subject/method/singleton_spec.rb +0 -61
  230. data/spec/unit/mutant/subject_spec.rb +0 -93
  231. data/spec/unit/mutant/transform/array_spec.rb +0 -92
  232. data/spec/unit/mutant/transform/bool_spec.rb +0 -63
  233. data/spec/unit/mutant/transform/error_spec.rb +0 -132
  234. data/spec/unit/mutant/transform/exception_spec.rb +0 -44
  235. data/spec/unit/mutant/transform/hash_spec.rb +0 -236
  236. data/spec/unit/mutant/transform/index_spec.rb +0 -92
  237. data/spec/unit/mutant/transform/named_spec.rb +0 -49
  238. data/spec/unit/mutant/transform/primitive_spec.rb +0 -56
  239. data/spec/unit/mutant/transform/sequence_spec.rb +0 -98
  240. data/spec/unit/mutant/util/one_spec.rb +0 -22
  241. data/spec/unit/mutant/warnings_spec.rb +0 -89
  242. data/spec/unit/mutant/world_spec.rb +0 -63
  243. data/spec/unit/mutant/zombifier_spec.rb +0 -122
  244. data/test_app/.rspec +0 -1
  245. data/test_app/Gemfile.minitest +0 -4
  246. data/test_app/Gemfile.rspec3.8 +0 -7
  247. data/test_app/lib/test_app.rb +0 -110
  248. data/test_app/lib/test_app/literal.rb +0 -35
  249. data/test_app/lib/test_app/metaclasses.rb +0 -108
  250. data/test_app/spec/spec_helper.rb +0 -9
  251. data/test_app/spec/unit/test_app/literal_spec.rb +0 -20
  252. data/test_app/test/unit/test_app/literal_test.rb +0 -16
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Mutant::Subject do
4
- let(:class_under_test) do
5
- Class.new(described_class) do
6
- def expression
7
- Mutant::Expression::Namespace::Exact.new(scope_name: 'SubjectA')
8
- end
9
-
10
- def match_expressions
11
- [
12
- expression,
13
- Mutant::Expression::Namespace::Exact.new(scope_name: 'SubjectB')
14
- ]
15
- end
16
- end
17
- end
18
-
19
- let(:object) do
20
- class_under_test.new(
21
- context: context,
22
- node: node,
23
- warnings: warnings
24
- )
25
- end
26
-
27
- let(:node) do
28
- Unparser.parse(<<-RUBY)
29
- def foo
30
- end
31
- RUBY
32
- end
33
-
34
- let(:context) do
35
- double(
36
- 'Context',
37
- source_path: 'source_path'
38
- )
39
- end
40
-
41
- let(:warnings) { instance_double(Mutant::Warnings) }
42
-
43
- describe '#identification' do
44
- subject { object.identification }
45
-
46
- it { should eql('SubjectA:source_path:1') }
47
- end
48
-
49
- describe '#source_line' do
50
- subject { object.source_line }
51
-
52
- it { should be(1) }
53
- end
54
-
55
- describe '#source_lines' do
56
- subject { object.source_lines }
57
-
58
- it { should eql(1..2) }
59
- end
60
-
61
- describe '#prepare' do
62
- subject { object.prepare }
63
-
64
- it_should_behave_like 'a command method'
65
- end
66
-
67
- describe '#node' do
68
- subject { object.node }
69
-
70
- it { should be(node) }
71
-
72
- it_should_behave_like 'an idempotent method'
73
- end
74
-
75
- describe '#mutations' do
76
- subject { object.mutations }
77
-
78
- before do
79
- expect(Mutant::Mutator).to receive(:mutate).with(node).and_return([mutation_a, mutation_b])
80
- end
81
-
82
- let(:mutation_a) { instance_double(Parser::AST::Node, :mutation_a) }
83
- let(:mutation_b) { instance_double(Parser::AST::Node, :mutation_b) }
84
-
85
- it 'generates neutral and evil mutations' do
86
- should eql([
87
- Mutant::Mutation::Neutral.new(object, node),
88
- Mutant::Mutation::Evil.new(object, mutation_a),
89
- Mutant::Mutation::Evil.new(object, mutation_b)
90
- ])
91
- end
92
- end
93
- end
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Mutant::Transform::Array do
4
- subject { described_class.new(transform) }
5
-
6
- let(:transform) { Mutant::Transform::Boolean.new }
7
-
8
- describe '#apply' do
9
- def apply
10
- subject.apply(input)
11
- end
12
-
13
- context 'on array input' do
14
- context 'empty' do
15
- let(:input) { [] }
16
-
17
- it 'returns sucess' do
18
- expect(apply).to eql(Mutant::Either::Right.new(input))
19
- end
20
- end
21
-
22
- context 'valid elements' do
23
- let(:input) { [true, true] }
24
-
25
- it 'returns sucess' do
26
- expect(apply).to eql(Mutant::Either::Right.new(input))
27
- end
28
- end
29
-
30
- context 'invalid elements' do
31
- let(:input) { [true, 1] }
32
-
33
- let(:boolean_error) do
34
- Mutant::Transform::Error.new(
35
- cause: nil,
36
- input: 1,
37
- message: 'Expected: boolean but got: 1',
38
- transform: transform
39
- )
40
- end
41
-
42
- let(:index_error) do
43
- Mutant::Transform::Error.new(
44
- cause: boolean_error,
45
- input: 1,
46
- message: nil,
47
- transform: Mutant::Transform::Index.new(index: 1, transform: transform)
48
- )
49
- end
50
-
51
- let(:error) do
52
- Mutant::Transform::Error.new(
53
- cause: index_error,
54
- input: input,
55
- message: 'Failed to coerce array at index: 1',
56
- transform: subject
57
- )
58
- end
59
-
60
- it 'returns failure' do
61
- expect(apply).to eql(Mutant::Either::Left.new(error))
62
- end
63
- end
64
-
65
- context 'transformed elements' do
66
- let(:input) { [{ 'foo' => 'bar' }] }
67
- let(:transform) { Mutant::Transform::Hash::Symbolize.new }
68
-
69
- it 'returns transformed elements' do
70
- expect(apply).to eql(Mutant::Either::Right.new([foo: 'bar']))
71
- end
72
- end
73
- end
74
-
75
- context 'on other input' do
76
- let(:input) { false }
77
-
78
- let(:error) do
79
- Mutant::Transform::Error.new(
80
- cause: nil,
81
- input: input,
82
- message: 'Expected: Array but got: FalseClass',
83
- transform: subject
84
- )
85
- end
86
-
87
- it 'returns failure' do
88
- expect(apply).to eql(Mutant::Either::Left.new(error))
89
- end
90
- end
91
- end
92
- end
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Mutant::Transform::Boolean do
4
- subject { described_class.new }
5
-
6
- let(:primitive) { String }
7
-
8
- describe '#apply' do
9
- def apply
10
- subject.apply(input)
11
- end
12
-
13
- context 'on true' do
14
- let(:input) { true }
15
-
16
- it 'returns sucess' do
17
- expect(apply).to eql(Mutant::Either::Right.new(input))
18
- end
19
- end
20
-
21
- context 'on false' do
22
- let(:input) { false }
23
-
24
- it 'returns sucess' do
25
- expect(apply).to eql(Mutant::Either::Right.new(input))
26
- end
27
- end
28
-
29
- context 'on nil input' do
30
- let(:input) { nil }
31
-
32
- let(:error) do
33
- Mutant::Transform::Error.new(
34
- cause: nil,
35
- input: input,
36
- message: 'Expected: boolean but got: nil',
37
- transform: subject
38
- )
39
- end
40
-
41
- it 'returns failure' do
42
- expect(apply).to eql(Mutant::Either::Left.new(error))
43
- end
44
- end
45
-
46
- context 'on truthy input' do
47
- let(:input) { '' }
48
-
49
- let(:error) do
50
- Mutant::Transform::Error.new(
51
- cause: nil,
52
- input: input,
53
- message: 'Expected: boolean but got: ""',
54
- transform: subject
55
- )
56
- end
57
-
58
- it 'returns failure' do
59
- expect(apply).to eql(Mutant::Either::Left.new(error))
60
- end
61
- end
62
- end
63
- end
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Mutant::Transform::Error do
4
- subject { described_class.new(attributes) }
5
-
6
- let(:message) { 'root-message' }
7
- let(:direct_cause) { nil }
8
- let(:indirect_cause) { nil }
9
-
10
- let(:attributes) do
11
- transform =
12
- if direct_cause
13
- Mutant::Transform::Named.new('root', direct_cause.transform)
14
- else
15
- Mutant::Transform::Boolean.new
16
- end
17
-
18
- {
19
- cause: direct_cause,
20
- input: nil,
21
- message: message,
22
- transform: transform
23
- }
24
- end
25
-
26
- shared_context 'direct cause' do
27
- let(:direct_cause) do
28
- transform =
29
- if indirect_cause
30
- Mutant::Transform::Named.new('direct-cause', indirect_cause.transform)
31
- else
32
- Mutant::Transform::Boolean.new
33
- end
34
-
35
- described_class.new(
36
- cause: indirect_cause,
37
- input: nil,
38
- message: 'direct-cause-message',
39
- transform: transform
40
- )
41
- end
42
- end
43
-
44
- shared_examples 'indirect cause' do
45
- let(:indirect_cause) do
46
- described_class.new(
47
- cause: nil,
48
- input: nil,
49
- message: 'indirect-cause-message',
50
- transform: Mutant::Transform::Boolean.new
51
- )
52
- end
53
- end
54
-
55
- describe '#trace' do
56
- def apply
57
- subject.trace
58
- end
59
-
60
- context 'without cause' do
61
- it 'returns path to self' do
62
- expect(apply).to eql([subject])
63
- end
64
- end
65
-
66
- context 'with direct cause' do
67
- include_context 'direct cause'
68
-
69
- it 'returns path to direct cause' do
70
- expect(apply).to eql([subject, direct_cause])
71
- end
72
- end
73
-
74
- context 'with indirect cause' do
75
- include_context 'direct cause'
76
- include_context 'indirect cause'
77
-
78
- it 'returns path to direct cause' do
79
- expect(apply).to eql([subject, direct_cause, indirect_cause])
80
- end
81
- end
82
- end
83
-
84
- describe '#compact_message' do
85
- def apply
86
- subject.compact_message
87
- end
88
-
89
- context 'root cause' do
90
- it 'returns expected message' do
91
- expect(apply).to eql('Mutant::Transform::Boolean: root-message')
92
- end
93
- end
94
-
95
- context 'with direct cause' do
96
- include_context 'direct cause'
97
-
98
- it 'returns expected message' do
99
- expect(apply).to eql(<<~'MESSAGE'.chomp)
100
- root/Mutant::Transform::Boolean: direct-cause-message
101
- MESSAGE
102
- end
103
- end
104
-
105
- context 'with indirect cause' do
106
- include_context 'direct cause'
107
- include_context 'indirect cause'
108
-
109
- context 'with present slugs' do
110
- it 'returns expected message' do
111
- expect(apply).to eql(<<~'MESSAGE'.chomp)
112
- root/direct-cause/Mutant::Transform::Boolean: indirect-cause-message
113
- MESSAGE
114
- end
115
- end
116
-
117
- context 'with empty slug' do
118
- let(:direct_cause) do
119
- super().with(
120
- transform: Mutant::Transform::Named.new('', indirect_cause.transform)
121
- )
122
- end
123
-
124
- it 'returns expected message' do
125
- expect(apply).to eql(<<~'MESSAGE'.chomp)
126
- root/Mutant::Transform::Boolean: indirect-cause-message
127
- MESSAGE
128
- end
129
- end
130
- end
131
- end
132
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Mutant::Transform::Exception do
4
- subject { described_class.new(error_class, block) }
5
-
6
- let(:error_class) do
7
- Class.new(RuntimeError)
8
- end
9
-
10
- describe '#apply' do
11
- def apply
12
- subject.apply(input)
13
- end
14
-
15
- let(:input) { 2 }
16
-
17
- context 'block that does not raise' do
18
- let(:block) { ->(input) { input*input } }
19
-
20
- it 'returns expected success value' do
21
- expect(apply).to eql(Mutant::Either::Right.new(4))
22
- end
23
- end
24
-
25
- context 'on block that raises' do
26
- context 'a covered exception' do
27
- let(:block) { ->(_input) { fail(error_class, 'some message') } }
28
-
29
- let(:error) do
30
- Mutant::Transform::Error.new(
31
- cause: nil,
32
- input: input,
33
- message: 'some message',
34
- transform: subject
35
- )
36
- end
37
-
38
- it 'returns expected error' do
39
- expect(apply).to eql(Mutant::Either::Left.new(error))
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,236 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe Mutant::Transform::Hash do
4
- subject { described_class.new(attributes) }
5
-
6
- let(:required) { [] }
7
- let(:optional) { [] }
8
- let(:symbol) { Mutant::Transform::Primitive.new(Symbol) }
9
-
10
- let(:attributes) do
11
- {
12
- required: required,
13
- optional: optional
14
- }
15
- end
16
-
17
- describe '#apply' do
18
- def apply
19
- subject.apply(input)
20
- end
21
-
22
- context 'on Hash input' do
23
- context 'empty' do
24
- let(:input) { {} }
25
-
26
- it 'returns sucess' do
27
- expect(apply).to eql(Mutant::Either::Right.new(input))
28
- end
29
- end
30
-
31
- context 'missing key' do
32
- let(:input) { {} }
33
- let(:required) { [described_class::Key.new(:foo, symbol)] }
34
-
35
- let(:error) do
36
- Mutant::Transform::Error.new(
37
- cause: nil,
38
- input: input,
39
- message: 'Missing keys: [:foo], Unexpected keys: []',
40
- transform: subject
41
- )
42
- end
43
-
44
- it 'returns error' do
45
- expect(apply).to eql(Mutant::Either::Left.new(error))
46
- end
47
- end
48
-
49
- context 'extra key' do
50
- let(:input) { { foo: :bar } }
51
-
52
- let(:error) do
53
- Mutant::Transform::Error.new(
54
- cause: nil,
55
- input: input,
56
- message: 'Missing keys: [], Unexpected keys: [:foo]',
57
- transform: subject
58
- )
59
- end
60
-
61
- it 'returns error' do
62
- expect(apply).to eql(Mutant::Either::Left.new(error))
63
- end
64
- end
65
-
66
- context 'using required' do
67
- let(:input) { { foo: :bar } }
68
- let(:required) { [described_class::Key.new(:foo, symbol)] }
69
-
70
- it 'returns success' do
71
- expect(apply).to eql(Mutant::Either::Right.new(input))
72
- end
73
- end
74
-
75
- context 'using optional' do
76
- let(:optional) { [described_class::Key.new(:foo, symbol)] }
77
-
78
- context 'not providing the optional key' do
79
- let(:input) { {} }
80
-
81
- it 'returns success' do
82
- expect(apply).to eql(Mutant::Either::Right.new(input))
83
- end
84
- end
85
-
86
- context 'providing the optional key' do
87
- let(:input) { { foo: :bar } }
88
-
89
- it 'returns success' do
90
- expect(apply).to eql(Mutant::Either::Right.new(input))
91
- end
92
- end
93
- end
94
-
95
- shared_examples 'key transform error' do
96
- let(:innermost_error) do
97
- Mutant::Transform::Error.new(
98
- cause: nil,
99
- input: 'bar',
100
- message: 'Expected: Symbol but got: String',
101
- transform: symbol
102
- )
103
- end
104
-
105
- let(:inner_error) do
106
- Mutant::Transform::Error.new(
107
- cause: innermost_error,
108
- input: 'bar',
109
- message: nil,
110
- transform: key_transform
111
- )
112
- end
113
-
114
- let(:error) do
115
- Mutant::Transform::Error.new(
116
- cause: inner_error,
117
- input: input,
118
- message: nil,
119
- transform: subject
120
- )
121
- end
122
-
123
- it 'returns failure' do
124
- expect(apply).to eql(Mutant::Either::Left.new(error))
125
- end
126
- end
127
-
128
- context 'key transform error' do
129
- let(:input) { { foo: 'bar' } }
130
-
131
- let(:key_transform) { described_class::Key.new(:foo, symbol) }
132
-
133
- context 'on optional key' do
134
- let(:optional) { [key_transform] }
135
-
136
- include_examples 'key transform error'
137
- end
138
-
139
- context 'on required key' do
140
- let(:required) { [key_transform] }
141
-
142
- include_examples 'key transform error'
143
- end
144
- end
145
- end
146
-
147
- context 'on other input' do
148
- let(:input) { [] }
149
-
150
- let(:error) do
151
- Mutant::Transform::Error.new(
152
- cause: nil,
153
- input: input,
154
- message: 'Expected: Hash but got: Array',
155
- transform: subject
156
- )
157
- end
158
-
159
- it 'returns failure' do
160
- expect(apply).to eql(Mutant::Either::Left.new(error))
161
- end
162
- end
163
- end
164
- end
165
-
166
- RSpec.describe Mutant::Transform::Hash::Symbolize do
167
- subject { described_class.new }
168
-
169
- describe '#apply' do
170
- def apply
171
- subject.apply(input)
172
- end
173
-
174
- let(:input) { { 'foo' => 'bar' } }
175
-
176
- it 'returns success' do
177
- expect(apply).to eql(Mutant::Either::Right.new(foo: 'bar'))
178
- end
179
- end
180
- end
181
-
182
- RSpec.describe Mutant::Transform::Hash::Key do
183
- subject { described_class.new(:foo, boolean) }
184
-
185
- let(:boolean) { Mutant::Transform::Boolean.new }
186
-
187
- describe '#slug' do
188
- def apply
189
- subject.slug
190
- end
191
-
192
- it 'returns expected slug' do
193
- expect(apply).to eql('[:foo]')
194
- end
195
- end
196
-
197
- describe '#apply' do
198
- def apply
199
- subject.apply(input)
200
- end
201
-
202
- context 'on valid input' do
203
- let(:input) { true }
204
-
205
- it 'returns success' do
206
- expect(apply).to eql(Mutant::Either::Right.new(true))
207
- end
208
- end
209
-
210
- context 'on invalid input' do
211
- let(:input) { 1 }
212
-
213
- let(:inner_error) do
214
- Mutant::Transform::Error.new(
215
- cause: nil,
216
- input: 1,
217
- message: 'Expected: boolean but got: 1',
218
- transform: boolean
219
- )
220
- end
221
-
222
- let(:error) do
223
- Mutant::Transform::Error.new(
224
- cause: inner_error,
225
- input: 1,
226
- message: nil,
227
- transform: subject
228
- )
229
- end
230
-
231
- it 'returns failure' do
232
- expect(apply).to eql(Mutant::Either::Left.new(error))
233
- end
234
- end
235
- end
236
- end