mutest 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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