mutest 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3342b18bb835fa632f2c85bf0bf29eba742d3b2
4
- data.tar.gz: 646eead6d1d21490f3d5d8415da8386ea63869d2
3
+ metadata.gz: 882e92ac10cfa19bf05b12f38997801b2fced697
4
+ data.tar.gz: e73ae60634c05d15a3ecc32e3162f2d6d4d1f8ed
5
5
  SHA512:
6
- metadata.gz: 4d478337ef6a1dc3f078df73f18fbf48e0d1d139c6f1aa10de4d5dbe9ad37f1bda9738dba35b120461e3f1944fca26f23a7f5720bfe512c4eb0f6dc4d05fae03
7
- data.tar.gz: 88cf68d896d143db8f1418055ee7aba9f07f818587f1a88fbf9b9380c094f0e34532563955d0fb6fcdfcfb6cc532caa87739552525d392aea919739961c7e058
6
+ metadata.gz: 489fefd9e304924294d8f2176e875939960d78a39ac01f3f795294719cfe4284919358cebc9c20a6095f6aaff500fe417524a755d117185acc5b622aa018a66b
7
+ data.tar.gz: 6729e041f46105175f37d425f2fad5c774d7f05151557258260e5f9030cb86c374c9f4609e2bd82694dfd408ab9d10fc20199f34d1047787292af3d71d9a3ea9
@@ -35,7 +35,7 @@ GIT
35
35
  PATH
36
36
  remote: .
37
37
  specs:
38
- mutest (0.0.2)
38
+ mutest (0.0.3)
39
39
  abstract_type (~> 0.0.7)
40
40
  adamantium (~> 0.2.0)
41
41
  anima (~> 0.3.0)
@@ -101,7 +101,6 @@ GEM
101
101
  docile (1.1.5)
102
102
  equalizer (0.0.11)
103
103
  erubis (2.7.0)
104
- ffi (1.9.17)
105
104
  flay (2.8.1)
106
105
  erubis (~> 2.7.0)
107
106
  path_expander (~> 1.0)
@@ -204,7 +203,6 @@ PLATFORMS
204
203
  DEPENDENCIES
205
204
  bundler (~> 1.10)
206
205
  devtools (~> 0.1.16)
207
- ffi (~> 1.9.6)
208
206
  mutant!
209
207
  mutest!
210
208
  pry (~> 0.10)
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ namespace :metrics do
17
17
  ]
18
18
  arguments.concat(%w[--jobs 4]) if ENV.key?('CIRCLECI')
19
19
 
20
- arguments.concat(%w[-- Mutant*])
20
+ arguments.concat(%w[-- Mutest*])
21
21
 
22
22
  Kernel.system(*arguments) or fail 'Mutant task is not successful'
23
23
  end
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 16
3
- total_score: 1329
3
+ total_score: 1338
@@ -61,7 +61,7 @@ module Mutest
61
61
  # @return [String]
62
62
  def text
63
63
  if type.equal?(:interval)
64
- interval_text + suffix
64
+ Interval.new(min, max).to_s + suffix
65
65
  else
66
66
  suffix
67
67
  end
@@ -95,13 +95,35 @@ module Mutest
95
95
  QUANTIFIER_MAP.fetch(node.type)
96
96
  end
97
97
 
98
- # Interval text constructed from min and max
99
- #
100
- # @return [String]
101
- def interval_text
102
- interval = [min, max].map { |num| num if num > 0 }.uniq
103
- "{#{interval.join(',')}}"
104
- end
98
+ class Interval
99
+ include Concord.new(:min, :max)
100
+
101
+ def initialize(*)
102
+ super
103
+
104
+ unless valid_min? && valid_max?
105
+ fail ArgumentError, 'Unexpected quantifier interval bound.'
106
+ end
107
+ end
108
+
109
+ def to_s
110
+ "{#{compacted_interval.join(',')}}"
111
+ end
112
+
113
+ private
114
+
115
+ def compacted_interval
116
+ [min, max].map { |bound| bound if bound > 0 }.uniq
117
+ end
118
+
119
+ def valid_min?
120
+ min >= 0
121
+ end
122
+
123
+ def valid_max?
124
+ max > 0 || max.equal?(-1)
125
+ end
126
+ end # Interval
105
127
  end # ASTToExpression
106
128
 
107
129
  ASTToExpression::QUANTIFIER_MAP.keys.each(&method(:register))
@@ -150,7 +150,7 @@ module Mutest
150
150
  # Write a semantics warning
151
151
  #
152
152
  # @return [undefined]
153
- def semantics_warning(format, options)
153
+ def semantics_warning(format, **options)
154
154
  message = format % options
155
155
  warn(format(SEMANTICS_MESSAGE_FORMAT, message: message))
156
156
  end
@@ -40,13 +40,6 @@ module Mutest
40
40
  # @return [Parser::AST::Node]
41
41
  alias_method :dup_node, :dup_input
42
42
 
43
- # Original nodes children
44
- #
45
- # @return [Array<Parser::AST::Node>]
46
- def children
47
- node.children
48
- end
49
-
50
43
  # Dispatch on child index
51
44
  #
52
45
  # @param [Fixnum] index
@@ -22,8 +22,8 @@ module Mutest
22
22
  #
23
23
  # @return [undefined]
24
24
  def emit_optarg_body_assignments
25
- arguments.children.each do |argument|
26
- next unless n_optarg?(argument) && AST::Meta::Optarg.new(argument).used?
25
+ used_arguments.each do |argument|
26
+ next unless n_optarg?(argument)
27
27
 
28
28
  emit_body_prepend(s(:lvasgn, *argument))
29
29
  end
@@ -33,7 +33,7 @@ module Mutest
33
33
  #
34
34
  # @return [undefined]
35
35
  def emit_restarg_body_mutation
36
- arguments.children.each do |argument|
36
+ used_arguments.each do |argument|
37
37
  replacement =
38
38
  if n_restarg?(argument)
39
39
  s(:array)
@@ -47,6 +47,10 @@ module Mutest
47
47
  end
48
48
  end
49
49
 
50
+ def used_arguments
51
+ arguments.children.select { |arg| AST::Meta::Optarg.new(arg).used? }
52
+ end
53
+
50
54
  # Emit valid body ASTs depending on instance body
51
55
  #
52
56
  # @param node [Parser::AST::Node]
@@ -10,6 +10,9 @@ module Mutest
10
10
  regexp_possessive_one_or_more: :regexp_possessive_interval
11
11
  )
12
12
 
13
+ # -1 marks an infinite upper bound
14
+ UNBOUNDED = -1
15
+
13
16
  handle(*MAP.keys)
14
17
 
15
18
  children :min, :max, :subject
@@ -18,10 +21,12 @@ module Mutest
18
21
  #
19
22
  # @return [undefined]
20
23
  def dispatch
21
- emit(s(MAP.fetch(node.type), 2, -1, subject))
24
+ emit(s(MAP.fetch(node.type), 2, UNBOUNDED, subject))
22
25
  emit_subject_mutations
23
26
  emit(subject)
24
27
  end
28
+
29
+ private_constant(*constants(false))
25
30
  end # OneOrMore
26
31
  end # Regexp
27
32
  end # Node
@@ -13,11 +13,11 @@ module Mutest
13
13
  SELECTOR_REPLACEMENTS = IceNine.deep_freeze(
14
14
  __send__: %i[public_send],
15
15
  :[] => %i[at fetch key?],
16
- :< => %i[== <= eql? equal?],
16
+ :< => %i[== eql? equal?],
17
17
  :<= => %i[< == eql? equal?],
18
18
  :== => %i[eql? equal?],
19
19
  :=== => %i[kind_of?],
20
- :> => %i[== >= eql? equal?],
20
+ :> => %i[== eql? equal?],
21
21
  :>= => %i[> == eql? equal?],
22
22
  '=~': %i[match?],
23
23
  at: %i[fetch key?],
@@ -174,7 +174,7 @@ module Mutest
174
174
  #
175
175
  # @return [undefined]
176
176
  def emit_drop_mutation
177
- return if !selector.equal?(:[]) || !arguments.one? || !n_irange?(arguments.first)
177
+ return if !selector.equal?(:[]) || !arguments.one? || !n_irange?(Mutest::Util.one(arguments))
178
178
 
179
179
  start, ending = *arguments.first
180
180
 
@@ -239,8 +239,11 @@ module Mutest
239
239
  #
240
240
  # @return [undefined]
241
241
  def emit_argument_propagation
242
- node = arguments.first
243
- emit(node) if arguments.one? && !NOT_STANDALONE.include?(node.type)
242
+ return unless arguments.one?
243
+
244
+ node = Mutest::Util.one(arguments)
245
+
246
+ emit(node) unless NOT_STANDALONE.include?(node.type)
244
247
  end
245
248
 
246
249
  # Emit receiver mutations
@@ -1,4 +1,4 @@
1
1
  module Mutest
2
2
  # Current mutest version
3
- VERSION = '0.0.3'.freeze
3
+ VERSION = '0.0.4'.freeze
4
4
  end # Mutest
@@ -15,6 +15,16 @@ Mutest::Meta::Example.add :def do
15
15
  mutation 'def foo(a); super; end'
16
16
  end
17
17
 
18
+ Mutest::Meta::Example.add :def do
19
+ source 'def foo(**bar); end'
20
+
21
+ mutation 'def foo; end'
22
+ mutation 'def foo(**_bar); end'
23
+ mutation 'def foo(**bar); bar = {}; end'
24
+ mutation 'def foo(**bar); raise; end'
25
+ mutation 'def foo(**bar); super; end'
26
+ end
27
+
18
28
  Mutest::Meta::Example.add :def do
19
29
  source 'def foo(a = {}); end'
20
30
 
@@ -1,11 +1,11 @@
1
1
  Mutest::Meta::Example.add :kwarg do
2
- source 'def foo(bar: baz); end'
2
+ source 'def foo(bar: {}); end'
3
3
 
4
4
  mutation 'def foo; end'
5
- mutation 'def foo(bar: baz); raise; end'
6
- mutation 'def foo(bar: baz); super; end'
5
+ mutation 'def foo(bar: {}); raise; end'
6
+ mutation 'def foo(bar: {}); super; end'
7
7
  mutation 'def foo(bar: nil); end'
8
8
  mutation 'def foo(bar: self); end'
9
9
  mutation 'def foo(bar:); end'
10
- mutation 'def foo(_bar: baz); end'
10
+ mutation 'def foo(_bar: {}); end'
11
11
  end
@@ -8,6 +8,14 @@ Mutest::Meta::Example.add :kwrestarg do
8
8
  mutation 'def foo(**bar); super; end'
9
9
  end
10
10
 
11
+ Mutest::Meta::Example.add :kwrestarg do
12
+ source 'def foo(**_bar); end'
13
+
14
+ mutation 'def foo; end'
15
+ mutation 'def foo(**_bar); raise; end'
16
+ mutation 'def foo(**_bar); super; end'
17
+ end
18
+
11
19
  Mutest::Meta::Example.add :kwrestarg do
12
20
  source 'def foo(**); end'
13
21
 
@@ -7,3 +7,11 @@ Mutest::Meta::Example.add :restarg do
7
7
  mutation 'def foo(*bar); raise; end'
8
8
  mutation 'def foo(*bar); super; end'
9
9
  end
10
+
11
+ Mutest::Meta::Example.add :restarg do
12
+ source 'def foo(*_bar); end'
13
+
14
+ mutation 'def foo; end'
15
+ mutation 'def foo(*_bar); raise; end'
16
+ mutation 'def foo(*_bar); super; end'
17
+ end
@@ -3,7 +3,6 @@ Mutest::Meta::Example.add :send do
3
3
 
4
4
  singleton_mutations
5
5
  mutation 'a == b'
6
- mutation 'a >= b'
7
6
  mutation 'a.eql?(b)'
8
7
  mutation 'a.equal?(b)'
9
8
  mutation 'nil > b'
@@ -28,6 +27,37 @@ Mutest::Meta::Example.add :send do
28
27
  mutation 'self.const_get(:B)'
29
28
  end
30
29
 
30
+ Mutest::Meta::Example.add :send do
31
+ source 'A.const_get(:B, true)'
32
+
33
+ singleton_mutations
34
+ mutation 'A'
35
+ mutation 'A::B'
36
+ mutation 'self.const_get(:B, true)'
37
+ mutation 'A.const_get'
38
+ mutation 'A.const_get(nil, true)'
39
+ mutation 'A.const_get(self, true)'
40
+ mutation 'A.const_get(:B__mutest__, true)'
41
+ mutation 'A.const_get(true)'
42
+ mutation 'A.const_get(:B, nil)'
43
+ mutation 'A.const_get(:B, false)'
44
+ mutation 'A.const_get(:B)'
45
+ end
46
+
47
+ Mutest::Meta::Example.add :send do
48
+ source 'A.const_get(:B)'
49
+
50
+ singleton_mutations
51
+ mutation 'A::B'
52
+ mutation 'A.const_get'
53
+ mutation 'A'
54
+ mutation ':B'
55
+ mutation 'A.const_get(nil)'
56
+ mutation 'A.const_get(self)'
57
+ mutation 'A.const_get(:B__mutest__)'
58
+ mutation 'self.const_get(:B)'
59
+ end
60
+
31
61
  Mutest::Meta::Example.add :send do
32
62
  source 'A.const_get(bar)'
33
63
 
@@ -88,7 +118,6 @@ Mutest::Meta::Example.add :send do
88
118
 
89
119
  singleton_mutations
90
120
  mutation 'a == b'
91
- mutation 'a <= b'
92
121
  mutation 'a.eql?(b)'
93
122
  mutation 'a.equal?(b)'
94
123
  mutation 'nil < b'
@@ -41,5 +41,4 @@ Gem::Specification.new do |gem|
41
41
  gem.add_development_dependency('rubocop-rspec', '~> 1.10.0')
42
42
  gem.add_development_dependency('devtools', '~> 0.1.16')
43
43
  gem.add_development_dependency('bundler', '~> 1.10')
44
- gem.add_development_dependency('ffi', '~> 1.9.6')
45
44
  end
@@ -623,3 +623,32 @@ RegexpSpec.expect_mapping(/\*/, :regexp_zero_or_more_escape) do
623
623
  s(:regexp_root_expression,
624
624
  s(:regexp_zero_or_more_escape))
625
625
  end
626
+
627
+ RSpec.describe Mutest::AST::Regexp::Transformer::Quantifier do # rubocop:disable RSpec/FilePath
628
+ def regexp(lower_bound, upper_bound)
629
+ sexp =
630
+ s(:regexp_root_expression,
631
+ s(:regexp_greedy_interval, lower_bound, upper_bound,
632
+ s(:regexp_literal_literal, 'a')))
633
+
634
+ Mutest::AST::Regexp.to_expression(sexp).to_re
635
+ end
636
+
637
+ shared_examples 'an invalid quantifier range' do |lower_bound, upper_bound|
638
+ it 'raises an error' do
639
+ expect { regexp(lower_bound, upper_bound) }
640
+ .to raise_error(ArgumentError, 'Unexpected quantifier interval bound.')
641
+ end
642
+ end
643
+
644
+ include_examples 'an invalid quantifier range', -1, 1
645
+ include_examples 'an invalid quantifier range', 1, 0
646
+
647
+ it 'treats 0 as a sentinel value' do
648
+ expect(regexp(0, 1)).to eql(/a{,1}/)
649
+ end
650
+
651
+ it 'treats -1 as a sentinel value' do
652
+ expect(regexp(1, -1)).to eql(/a{1,}/)
653
+ end
654
+ end
@@ -110,6 +110,16 @@ RSpec.describe Mutest::Context do
110
110
  end
111
111
  end
112
112
 
113
+ describe '#source_path' do
114
+ let(:source_file) do
115
+ instance_double(Mutest::SourceFile, path: instance_double(Pathname))
116
+ end
117
+
118
+ it 'exposes source file path' do
119
+ expect(described_class.new(scope, source_file).source_path).to be(source_file.path)
120
+ end
121
+ end
122
+
113
123
  describe '#ignore?' do
114
124
  let(:object) do
115
125
  described_class.new(scope, source_file)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Gollahon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-01-31 00:00:00.000000000 Z
12
+ date: 2017-02-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parser
@@ -269,20 +269,6 @@ dependencies:
269
269
  - - "~>"
270
270
  - !ruby/object:Gem::Version
271
271
  version: '1.10'
272
- - !ruby/object:Gem::Dependency
273
- name: ffi
274
- requirement: !ruby/object:Gem::Requirement
275
- requirements:
276
- - - "~>"
277
- - !ruby/object:Gem::Version
278
- version: 1.9.6
279
- type: :development
280
- prerelease: false
281
- version_requirements: !ruby/object:Gem::Requirement
282
- requirements:
283
- - - "~>"
284
- - !ruby/object:Gem::Version
285
- version: 1.9.6
286
272
  description: Mutation testing for ruby
287
273
  email:
288
274
  - johncbackus@gmail.com
@@ -581,7 +567,6 @@ files:
581
567
  - spec/support/fake_actor.rb
582
568
  - spec/support/file_system.rb
583
569
  - spec/support/ice_nine_config.rb
584
- - spec/support/rb_bug.rb
585
570
  - spec/support/ruby_vm.rb
586
571
  - spec/support/shared_context.rb
587
572
  - spec/support/test_app.rb
@@ -1,15 +0,0 @@
1
- require 'ffi'
2
-
3
- # @api private
4
- module RbBug
5
- extend FFI::Library
6
- ffi_lib 'ruby'
7
- attach_function :rb_bug, %i[string varargs], :void
8
-
9
- # Call the test bug
10
- #
11
- # @return [undefined]
12
- def self.call
13
- rb_bug('%s', :string, 'test bug')
14
- end
15
- end # RbBug