2014-06-02 08:57:14 -04:00
|
|
|
module Mutant
|
|
|
|
module Meta
|
|
|
|
class Example
|
|
|
|
|
|
|
|
# Example DSL
|
|
|
|
class DSL
|
2014-06-29 17:25:17 -04:00
|
|
|
include AST::Sexp
|
2014-06-02 08:57:14 -04:00
|
|
|
|
|
|
|
# Run DSL on block
|
|
|
|
#
|
|
|
|
# @return [Example]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2014-08-16 17:13:41 -04:00
|
|
|
def self.run(file, block)
|
|
|
|
instance = new(file)
|
2014-06-02 08:57:14 -04:00
|
|
|
instance.instance_eval(&block)
|
|
|
|
instance.example
|
|
|
|
end
|
|
|
|
|
|
|
|
# Initialize DSL context
|
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
2014-08-16 17:13:41 -04:00
|
|
|
def initialize(file)
|
|
|
|
@file = file
|
2014-06-02 08:57:14 -04:00
|
|
|
@source = nil
|
|
|
|
@expected = []
|
|
|
|
end
|
|
|
|
|
|
|
|
# Return example
|
|
|
|
#
|
|
|
|
# @return [Example]
|
|
|
|
#
|
|
|
|
# @raise [RuntimeError]
|
|
|
|
# in case example cannot be build
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def example
|
2014-11-17 12:00:05 -05:00
|
|
|
fail 'source not defined' unless @source
|
2014-08-16 17:13:41 -04:00
|
|
|
Example.new(@file, @source, @expected)
|
2014-06-02 08:57:14 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
# Set original source
|
|
|
|
#
|
|
|
|
# @param [String,Parser::AST::Node] input
|
|
|
|
#
|
|
|
|
# @return [self]
|
|
|
|
#
|
2014-06-28 16:52:47 -04:00
|
|
|
# @api private
|
|
|
|
#
|
2014-06-02 08:57:14 -04:00
|
|
|
def source(input)
|
2014-11-17 12:00:05 -05:00
|
|
|
fail 'source already defined' if @source
|
2014-06-02 08:57:14 -04:00
|
|
|
@source = node(input)
|
|
|
|
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
|
|
|
# Add expected mutation
|
|
|
|
#
|
|
|
|
# @param [String,Parser::AST::Node] input
|
|
|
|
#
|
|
|
|
# @return [self]
|
|
|
|
#
|
2014-06-28 16:52:47 -04:00
|
|
|
# @api private
|
|
|
|
#
|
2014-06-02 08:57:14 -04:00
|
|
|
def mutation(input)
|
|
|
|
node = node(input)
|
|
|
|
if @expected.include?(node)
|
2014-11-17 12:00:05 -05:00
|
|
|
fail "Node for input: #{input.inspect} is already expected"
|
2014-06-02 08:57:14 -04:00
|
|
|
end
|
|
|
|
@expected << node
|
|
|
|
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2014-08-07 12:00:31 -04:00
|
|
|
# Add singleton mutations
|
2014-06-05 12:37:31 -04:00
|
|
|
#
|
|
|
|
# @return [undefined]
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def singleton_mutations
|
2014-06-09 10:56:13 -04:00
|
|
|
mutation('nil')
|
|
|
|
mutation('self')
|
2014-06-05 12:37:31 -04:00
|
|
|
end
|
|
|
|
|
2014-06-02 08:57:14 -04:00
|
|
|
# Helper method to coerce input to node
|
|
|
|
#
|
|
|
|
# @param [String,Parser::AST::Node] input
|
|
|
|
#
|
|
|
|
# @return [Parser::AST::Node]
|
|
|
|
#
|
|
|
|
# @raise [RuntimeError]
|
|
|
|
# in case input cannot be coerced
|
|
|
|
#
|
|
|
|
# @api private
|
|
|
|
#
|
|
|
|
def node(input)
|
2014-06-09 10:56:13 -04:00
|
|
|
case input
|
|
|
|
when String
|
|
|
|
Unparser::Preprocessor.run(Parser::CurrentRuby.parse(input))
|
|
|
|
when Parser::AST::Node
|
|
|
|
input
|
|
|
|
else
|
2014-11-17 12:00:05 -05:00
|
|
|
fail "Cannot coerce to node: #{source.inspect}"
|
2014-06-09 10:56:13 -04:00
|
|
|
end
|
2014-06-02 08:57:14 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
end # DSL
|
|
|
|
end # Example
|
|
|
|
end # Meta
|
|
|
|
end # Mutant
|