104 lines
2.1 KiB
Ruby
104 lines
2.1 KiB
Ruby
# encoding: utf-8
|
|
|
|
class Subject
|
|
|
|
include Equalizer.new(:source)
|
|
|
|
Undefined = Object.new.freeze
|
|
|
|
attr_reader :source
|
|
|
|
def self.coerce(input)
|
|
case input
|
|
when Parser::AST::Node
|
|
new(input)
|
|
when String
|
|
new(Parser::CurrentRuby.parse(input))
|
|
else
|
|
raise
|
|
end
|
|
end
|
|
|
|
def to_s
|
|
"#{@node.inspect}\n#{@source}"
|
|
end
|
|
|
|
def initialize(node)
|
|
source = Unparser.unparse(node)
|
|
@node, @source = node, source
|
|
end
|
|
|
|
def assert_transitive!
|
|
generated = Unparser.generate(@node)
|
|
parsed = Parser::CurrentRuby.parse(generated)
|
|
again = Unparser.generate(parsed)
|
|
unless generated == again
|
|
# mostly an unparser bug!
|
|
fail sprintf("Untransitive:\n%s\n---\n%s", generated, again)
|
|
end
|
|
self
|
|
end
|
|
end
|
|
|
|
shared_examples_for 'a mutator' do
|
|
subject { object.each(node) { |item| yields << item } }
|
|
|
|
let(:yields) { [] }
|
|
let(:object) { described_class }
|
|
|
|
unless instance_methods.map(&:to_s).include?('node')
|
|
let(:node) { parse(source) }
|
|
end
|
|
|
|
it_should_behave_like 'a command method'
|
|
|
|
context 'with no block' do
|
|
subject { object.each(node) }
|
|
|
|
it { should be_instance_of(to_enum.class) }
|
|
|
|
let(:expected_mutations) do
|
|
mutations.map(&Subject.method(:coerce))
|
|
end
|
|
|
|
let(:generated_mutations) do
|
|
end
|
|
|
|
it 'generates the expected mutations' do
|
|
|
|
generated = subject.map { |node| Subject.new(node) }
|
|
|
|
missing = expected_mutations - generated
|
|
unexpected = generated - expected_mutations
|
|
|
|
message = []
|
|
|
|
if missing.any?
|
|
message << sprintf('Missing mutations (%i):', missing.length)
|
|
message.concat(missing)
|
|
end
|
|
|
|
if unexpected.any?
|
|
message << sprintf('Unexpected mutations (%i):', unexpected.length)
|
|
message.concat(unexpected)
|
|
end
|
|
|
|
if message.any?
|
|
|
|
message = sprintf(
|
|
"Original:\n%s\n-----\n%s",
|
|
generate(node),
|
|
message.join("\n-----\n")
|
|
)
|
|
|
|
fail message
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
shared_examples_for 'a noop mutator' do
|
|
let(:mutations) { [] }
|
|
|
|
it_should_behave_like 'a mutator'
|
|
end
|