Add mutation Date.parse
-> other parse methods
- Adds receiver specific selector mutations - Closes #432
This commit is contained in:
parent
9aec65b847
commit
7931a01476
8 changed files with 158 additions and 2 deletions
|
@ -1,3 +1,7 @@
|
|||
# Unreleased
|
||||
|
||||
* Add mutation from `Date.parse` to more strict parsing methods #448
|
||||
|
||||
# v0.8.5 2015-09-11
|
||||
|
||||
* Fix misimplementation of block gluing operator that
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
---
|
||||
threshold: 18
|
||||
total_score: 1233
|
||||
total_score: 1239
|
||||
|
|
|
@ -50,6 +50,7 @@ require 'mutant/ast/named_children'
|
|||
require 'mutant/ast/node_predicates'
|
||||
require 'mutant/ast/meta'
|
||||
require 'mutant/ast/meta/send'
|
||||
require 'mutant/ast/meta/const'
|
||||
require 'mutant/ast/meta/symbol'
|
||||
require 'mutant/ast/meta/optarg'
|
||||
require 'mutant/ast/meta/resbody'
|
||||
|
|
24
lib/mutant/ast/meta/const.rb
Normal file
24
lib/mutant/ast/meta/const.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
module Mutant
|
||||
module AST
|
||||
# Node meta information mixin
|
||||
module Meta
|
||||
|
||||
# Metadata for const nodes
|
||||
class Const
|
||||
include NamedChildren, Concord.new(:node), NodePredicates
|
||||
|
||||
children :base, :name
|
||||
|
||||
# Test if AST node is possibly a top level constant
|
||||
#
|
||||
# @return [Boolean]
|
||||
#
|
||||
# @api private
|
||||
def possible_top_level?
|
||||
base.nil? || n_cbase?(base)
|
||||
end
|
||||
|
||||
end # Const
|
||||
end # Meta
|
||||
end # AST
|
||||
end # Mutant
|
|
@ -5,7 +5,7 @@ module Mutant
|
|||
|
||||
# Metadata for send nodes
|
||||
class Send
|
||||
include NamedChildren, Concord.new(:node)
|
||||
include NamedChildren, Concord.new(:node), NodePredicates
|
||||
|
||||
children :receiver, :selector
|
||||
|
||||
|
@ -56,6 +56,17 @@ module Mutant
|
|||
Types::BINARY_METHOD_OPERATORS.include?(selector)
|
||||
end
|
||||
|
||||
# Test if receiver is possibly a top level constant
|
||||
#
|
||||
# @return [Boolean]
|
||||
#
|
||||
# @api private
|
||||
def receiver_possible_top_level_const?
|
||||
return false unless receiver && n_const?(receiver)
|
||||
|
||||
Const.new(receiver).possible_top_level?
|
||||
end
|
||||
|
||||
end # Send
|
||||
end # Meta
|
||||
end # AST
|
||||
|
|
|
@ -3,6 +3,7 @@ module Mutant
|
|||
class Node
|
||||
|
||||
# Namespace for send mutators
|
||||
# rubocop:disable ClassLength
|
||||
class Send < self
|
||||
include AST::Types
|
||||
|
||||
|
@ -34,6 +35,12 @@ module Mutant
|
|||
:< => %i[== <= eql? equal?]
|
||||
)
|
||||
|
||||
RECEIVER_SELECTOR_REPLACEMENTS = IceNine.deep_freeze(
|
||||
Date: {
|
||||
parse: %i[jd civil strptime iso8601 rfc3339 xmlschema rfc2822 rfc822 httpdate jisx0301]
|
||||
}
|
||||
)
|
||||
|
||||
private
|
||||
|
||||
# Perform dispatch
|
||||
|
@ -92,10 +99,25 @@ module Mutant
|
|||
emit_selector_replacement
|
||||
emit_const_get_mutation
|
||||
emit_argument_propagation
|
||||
emit_receiver_selector_mutations
|
||||
mutate_receiver
|
||||
mutate_arguments
|
||||
end
|
||||
|
||||
# Emit selector mutations specific to top level constants
|
||||
#
|
||||
# @return [undefined]
|
||||
#
|
||||
# @api private
|
||||
def emit_receiver_selector_mutations
|
||||
return unless meta.receiver_possible_top_level_const?
|
||||
|
||||
RECEIVER_SELECTOR_REPLACEMENTS
|
||||
.fetch(receiver.children.last, EMPTY_HASH)
|
||||
.fetch(selector, EMPTY_ARRAY)
|
||||
.each(&method(:emit_selector))
|
||||
end
|
||||
|
||||
# Emit mutation from `const_get` to const literal
|
||||
#
|
||||
# @return [undefined]
|
||||
|
|
57
meta/date.rb
Normal file
57
meta/date.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
Mutant::Meta::Example.add do
|
||||
source 'Date.parse(nil)'
|
||||
|
||||
singleton_mutations
|
||||
mutation 'Date.parse'
|
||||
mutation 'self.parse(nil)'
|
||||
mutation 'Date'
|
||||
mutation 'Date.jd(nil)'
|
||||
mutation 'Date.civil(nil)'
|
||||
mutation 'Date.strptime(nil)'
|
||||
mutation 'Date.iso8601(nil)'
|
||||
mutation 'Date.rfc3339(nil)'
|
||||
mutation 'Date.xmlschema(nil)'
|
||||
mutation 'Date.rfc2822(nil)'
|
||||
mutation 'Date.rfc822(nil)'
|
||||
mutation 'Date.httpdate(nil)'
|
||||
mutation 'Date.jisx0301(nil)'
|
||||
end
|
||||
|
||||
Mutant::Meta::Example.add do
|
||||
source '::Date.parse(nil)'
|
||||
|
||||
singleton_mutations
|
||||
mutation '::Date.parse'
|
||||
mutation 'Date.parse(nil)'
|
||||
mutation 'self.parse(nil)'
|
||||
mutation '::Date'
|
||||
mutation '::Date.jd(nil)'
|
||||
mutation '::Date.civil(nil)'
|
||||
mutation '::Date.strptime(nil)'
|
||||
mutation '::Date.iso8601(nil)'
|
||||
mutation '::Date.rfc3339(nil)'
|
||||
mutation '::Date.xmlschema(nil)'
|
||||
mutation '::Date.rfc2822(nil)'
|
||||
mutation '::Date.rfc822(nil)'
|
||||
mutation '::Date.httpdate(nil)'
|
||||
mutation '::Date.jisx0301(nil)'
|
||||
end
|
||||
|
||||
Mutant::Meta::Example.add do
|
||||
source 'Date.iso8601(nil)'
|
||||
|
||||
singleton_mutations
|
||||
mutation 'Date.iso8601'
|
||||
mutation 'self.iso8601(nil)'
|
||||
mutation 'Date'
|
||||
end
|
||||
|
||||
Mutant::Meta::Example.add do
|
||||
source 'Foo::Date.parse(nil)'
|
||||
|
||||
singleton_mutations
|
||||
mutation 'Foo::Date.parse'
|
||||
mutation 'Foo::Date'
|
||||
mutation 'Date.parse(nil)'
|
||||
mutation 'self.parse(nil)'
|
||||
end
|
|
@ -0,0 +1,37 @@
|
|||
RSpec.describe Mutant::AST::Meta::Send, '#receiver_possible_top_level_const?' do
|
||||
subject { described_class.new(node).receiver_possible_top_level_const? }
|
||||
|
||||
def parse(source)
|
||||
Parser::CurrentRuby.parse(source)
|
||||
end
|
||||
|
||||
context 'when implicit top level const' do
|
||||
let(:node) { parse('Foo.bar') }
|
||||
|
||||
it { should be true }
|
||||
end
|
||||
|
||||
context 'when cbase' do
|
||||
let(:node) { parse('::Foo.bar') }
|
||||
|
||||
it { should be true }
|
||||
end
|
||||
|
||||
context 'when nested const' do
|
||||
let(:node) { parse('Baz::Foo.bar') }
|
||||
|
||||
it { should be false }
|
||||
end
|
||||
|
||||
context 'when no receiver' do
|
||||
let(:node) { parse('bar') }
|
||||
|
||||
it { should be false }
|
||||
end
|
||||
|
||||
context 'when send receiver' do
|
||||
let(:node) { parse('foo.bar') }
|
||||
|
||||
it { should be false }
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue