Module: RSpec::Arguments

Included in:
MonkeyPatcher
Defined in:
lib/rspec/arguments/version.rb,
lib/rspec/arguments/arguments.rb,
lib/rspec/arguments/example_group.rb,
lib/rspec/arguments/monkey_patcher.rb

Defined Under Namespace

Modules: ExampleGroup, MonkeyPatcher

Constant Summary collapse

VERSION =
'0.2.0'
ARG_PREFIX =
'__arg_'.freeze
METHOD_ARG_PREFIX =
'__m_arg_'.freeze
POSITIONAL_ARG_SUFFIX =
'pos_'.freeze
KEYWORD_ARG_SUFFIX =
'kw_'.freeze
BLOCK_ARG_SUFFIX =
'blk_'.freeze
POSITIONAL_ARG =
ARG_PREFIX + POSITIONAL_ARG_SUFFIX
KEYWORD_ARG =
ARG_PREFIX + KEYWORD_ARG_SUFFIX
BLOCK_ARG =
ARG_PREFIX + BLOCK_ARG_SUFFIX
METHOD_POSITIONAL_ARG =
METHOD_ARG_PREFIX + POSITIONAL_ARG_SUFFIX
METHOD_KEYWORD_ARG =
METHOD_ARG_PREFIX + KEYWORD_ARG_SUFFIX
METHOD_BLOCK_ARG =
METHOD_ARG_PREFIX + BLOCK_ARG_SUFFIX

Instance Method Summary collapse

Instance Method Details

#call_initializer_with_args(receiver) ⇒ Object



95
96
97
98
99
100
101
102
103
104
# File 'lib/rspec/arguments/arguments.rb', line 95

def call_initializer_with_args(receiver)
  call_with_args(
    self.class.instance_methods,
    POSITIONAL_ARG,
    KEYWORD_ARG,
    BLOCK_ARG,
  ) do |*args, &block|
    receiver.new(*args, &block)
  end
end

#call_method_with_args(receiver, method_sym) ⇒ Object



106
107
108
109
110
111
112
113
114
115
# File 'lib/rspec/arguments/arguments.rb', line 106

def call_method_with_args(receiver, method_sym)
  call_with_args(
    self.class.instance_methods,
    METHOD_POSITIONAL_ARG,
    METHOD_KEYWORD_ARG,
    METHOD_BLOCK_ARG,
  ) do |*args, &block|
    receiver.send(method_sym, *args, &block)
  end
end

#call_with_args(list, positional_arg, keyword_arg, block_arg, &proc) ⇒ Object



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
# File 'lib/rspec/arguments/arguments.rb', line 36

def call_with_args(list, positional_arg, keyword_arg, block_arg, &proc)
  positional_args = []
  keyword_args = {}
  block_args = nil

  list.sort.each do |name|
    if name.to_s.start_with?(positional_arg)
      positional_args << send(name)
    elsif name.to_s.start_with?(keyword_arg)
      key = name[keyword_arg.size..-1].to_sym
      keyword_args[key] = send(name)
    elsif name.to_s.start_with?(block_arg)
      block_args = send(name)
    end
  end

  # DEBUG CODE
  # puts "positional_args #{positional_args}"
  # puts "keyword_args #{keyword_args}"
  # puts "block_arg #{block_args}"

  positional_args << keyword_args unless keyword_args.empty?

  proc.call(*positional_args, &block_args)
end

#method_under_test(key) ⇒ Object

Search for method under testing inside ExampleGroupHash metadata

TODO This can likely be improved by using TODO RSpec filtered extensions.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rspec/arguments/arguments.rb', line 68

def method_under_test(key)
  method_arg = self.class.[key]

  return unless method_arg

  # Return here if you were nice and declared
  # your method under test using
  # `method: :method_name`.
  return method_arg if method_arg.is_a?(Symbol)

  # Otherwise, we have to search for the described
  # name string somewhere in our ancestor chain.

  # If we are inside a nested example group,
  # recursively search ascendants' metadata
  # for the correct method under testing.
  method_name = search_method_name(self.class., key)
  method_name.sub('#', '').sub('.', '').to_sym
end

#process_instance_subject(clazz) ⇒ Object



26
27
28
29
30
31
32
33
34
# File 'lib/rspec/arguments/arguments.rb', line 26

def process_instance_subject(clazz)
  instance = call_initializer_with_args(clazz)

  method = method_under_test(:method)

  return instance unless method

  call_method_with_args(instance, method.to_sym)
end

#process_subject(clazz) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/rspec/arguments/arguments.rb', line 18

def process_subject(clazz)
  class_method = method_under_test(:class_method)

  return call_method_with_args(clazz, class_method.to_sym) if class_method

  process_instance_subject(clazz)
end

#search_method_name(metadata, key) ⇒ Object



88
89
90
91
92
93
# File 'lib/rspec/arguments/arguments.rb', line 88

def search_method_name(, key)
  description = [:description]
  return description unless [:parent_example_group] && [:parent_example_group][key]

  search_method_name([:parent_example_group], key) if [:parent_example_group]
end