1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
require "rspec/parameterized/version"
require 'parser'
require 'unparser'
require 'proc_to_ast'
module RSpec
module Parameterized
autoload :TableSyntax, 'rspec/parameterized/table_syntax'
module ExampleGroupMethods
# capsulize parameter attributes
class Parameter
attr_reader :arg_names, :block
def initialize(arg_names, &block)
@arg_names, @block = arg_names, block
end
end
# Set parameters to be bound in specs under this example group.
#
# ## Example1
#
# where(:a, :b, :answer) do
# [
# [1 , 2 , 3],
# [5 , 8 , 13],
# [0 , 0 , 0]
# ]
# end
#
# ## Example2
# using RSpec::Parameterized::TableSyntax
# where(:a, :b, :answer) do
# 1 | 2 | 3 >
# 5 | 8 | 13 >
# 0 | 0 | 0
# end
#
def where(*args, &b)
if args.size == 1 && args[0].instance_of?(Hash)
naming_func = args.first.delete(:case_names)
params = args[0]
first, *rest = params.values
arg_names = params.keys
arg_values = first.product(*rest)
if naming_func && naming_func.respond_to?(:call)
arg_names << :case_name
arg_values.map! { |row| row << naming_func.call(*row) }
end
set_parameters(arg_names) {
arg_values
}
elsif args.size == 0
set_verbose_parameters(&b)
else
set_parameters(args, &b)
end
end
# Use parameters to execute the block.
# The given block is converted into +describe+s for each parameter set.
#
# ## Example
# with_them do
# it "should do additions" do
# (a + b).should == answer
# end
# end
#
def with_them(*args, &b)
opts = args.last.is_a?(Hash) ? args.pop : {}
opts[:caller] = caller unless opts[:caller]
args.push(opts)
if @parameter.nil?
@parameterized_pending_cases ||= []
@parameterized_pending_cases << [args, b]
else
define_cases(@parameter, *args, &b)
end
end
private
def set_parameters(arg_names, &b)
@parameter = Parameter.new(arg_names, &b)
if @parameterized_pending_cases
@parameterized_pending_cases.each { |e|
define_cases(@parameter, *e[0], &e[1])
}
end
end
def define_cases(parameter, *args, &block)
instance = new # for evaluate let methods.
if defined?(self.superclass::LetDefinitions)
instance.extend self.superclass::LetDefinitions
end
extracted = instance.instance_eval(¶meter.block)
param_sets = extracted.is_a?(Array) ? extracted : extracted.to_params
# for only one parameters
param_sets = param_sets.map { |x| Array[x] } if !param_sets[0].is_a?(Array)
param_sets.each do |param_set|
pairs = [parameter.arg_names, param_set].transpose.to_h
pretty_params = pairs.has_key?(:case_name) ? pairs[:case_name] : pairs.map {|name, val| "#{name}: #{params_inspect(val)}"}.join(", ")
describe(pretty_params, *args) do
pairs.each do |name, val|
let(name) { val }
end
singleton_class.module_eval do
if respond_to?(:params)
warn "ExampleGroup.params method is overrided."
end
define_method(:params) do
pairs
end
if respond_to?(:all_params)
warn "ExampleGroup.all_params method is overrided."
end
define_method(:all_params) do
param_sets
end
end
module_eval(&block)
end
end
end
def params_inspect(obj)
begin
obj.is_a?(Proc) ? obj.to_raw_source : obj.inspect
rescue Parser::SyntaxError
return obj.inspect
end
end
def set_verbose_parameters(&block)
arguments_hash = yield
arg_names = arguments_hash.values.reduce(Set.new) { |memo, pairs| memo | pairs.keys }.to_a
arg_values = []
arguments_hash.each do |name, values_hash|
row = [name]
arg_names.each do |argument_name|
row << values_hash[argument_name]
end
arg_values << row
end
arg_names.unshift(:case_name)
set_parameters(arg_names) {
arg_values
}
end
end
end
module Core
class ExampleGroup
extend ::RSpec::Parameterized::ExampleGroupMethods
end
end
end
|