File: core.rb

package info (click to toggle)
ruby-rspec-parameterized-core 2.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 204 kB
  • sloc: ruby: 647; sh: 4; makefile: 4
file content (175 lines) | stat: -rw-r--r-- 5,296 bytes parent folder | download
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
174
175
require "rspec/parameterized/core/version"
require 'rspec/parameterized/core/helper_methods'
require 'rspec/parameterized/core/example_helper_methods'
require 'rspec/parameterized/core/errors'
require 'rspec/parameterized/core/composite_parser'

module RSpec
  module Parameterized
    module Core
      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)
          @parameter ||= nil

          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)
          @parameterized_pending_cases ||= []

          @parameterized_pending_cases.each { |e|
            define_cases(@parameter, *e[0], &e[1])
          }
        end

        def define_cases(parameter, *args, &block)
          instance = new  # for evaluate let methods.
          instance.extend HelperMethods
          if defined?(self.superclass::LetDefinitions)
            instance.extend self.superclass::LetDefinitions
          end

          extracted = instance.instance_eval(&parameter.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
              include ExampleHelperMethods

              pairs.each do |name, val|
                let(name) { recursive_apply(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)
          RSpec::Parameterized::Core::CompositeParser.to_raw_source(obj)
        rescue ParserSyntaxError
          return obj.inspect
        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
  end

  module Core
    class ExampleGroup
      extend ::RSpec::Parameterized::Core::ExampleGroupMethods
    end
  end
end