Class: Transpec::Syntax::Have

Inherits:
Transpec::Syntax show all
Includes:
Mixin::Send
Defined in:
lib/transpec/syntax/have.rb

Defined Under Namespace

Classes: DynamicInspector, HaveRecord

Constant Summary collapse

QUERY_METHOD_PRIORITIES =

String#count is not query method, and there’s no way to determine whether a method is query method. Method#arity and Method#parameters return same results for Array#count (0+ args) and String#count (1+ args).

So I make #size a priority over #count so that #count won’t be chosen for String (String responds to #size).

[:size, :count, :length].freeze

Instance Attribute Summary collapse

Attributes inherited from Transpec::Syntax

#node, #report, #runtime_data, #source_rewriter

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mixin::Send

#arg_node, #arg_nodes, #arg_range, #args_range, included, #method_name, #parentheses_range, #range_after_arg, #range_in_between_receiver_and_selector, #range_in_between_selector_and_arg, #receiver_node, #receiver_range, #selector_range

Methods inherited from Transpec::Syntax

conversion_target_node?, #expression_range, #parent_node, snake_case_name, #static_context_inspector, target_node?

Methods included from Collection

#all_syntaxes, #inherited, #require_all, #standalone_syntaxes

Methods included from DynamicAnalysis

#register_request_for_dynamic_analysis

Constructor Details

#initialize(node, expectation, source_rewriter = nil, runtime_data = nil, report = nil) ⇒ Have

Returns a new instance of Have.



33
34
35
36
37
38
39
# File 'lib/transpec/syntax/have.rb', line 33

def initialize(node, expectation, source_rewriter = nil, runtime_data = nil, report = nil)
  @node = node
  @expectation = expectation
  @source_rewriter = source_rewriter
  @runtime_data = runtime_data
  @report = report || Report.new
end

Instance Attribute Details

#expectationObject (readonly)

Returns the value of attribute expectation.



20
21
22
# File 'lib/transpec/syntax/have.rb', line 20

def expectation
  @expectation
end

Class Method Details

.standalone?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/transpec/syntax/have.rb', line 22

def self.standalone?
  false
end

.target_method?(have_node, items_method_name) ⇒ Boolean

Returns:

  • (Boolean)


26
27
28
29
30
31
# File 'lib/transpec/syntax/have.rb', line 26

def self.target_method?(have_node, items_method_name)
  return false unless have_node
  have_receiver_node, have_method_name, *_ = *have_node
  return false if have_receiver_node
  [:have, :have_exactly, :have_at_least, :have_at_most].include?(have_method_name)
end

Instance Method Details

#build_replacement_matcher_source(size_source, parenthesize_arg = true) ⇒ Object



134
135
136
137
138
139
140
141
# File 'lib/transpec/syntax/have.rb', line 134

def build_replacement_matcher_source(size_source, parenthesize_arg = true)
  case @expectation.current_syntax_type
  when :should
    build_replacement_matcher_source_for_should(size_source)
  when :expect
    build_replacement_matcher_source_for_expect(size_source, parenthesize_arg)
  end
end

#build_replacement_subject_source(original_subject_source) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/transpec/syntax/have.rb', line 116

def build_replacement_subject_source(original_subject_source)
  source = original_subject_source.dup
  if subject_is_owner_of_collection?
    if collection_accessor_is_private?
      source << ".send(#{collection_accessor.inspect}"
      source << ", #{args_range.source}" if items_method_has_arguments?
      source << ')'
    else
      source << ".#{collection_accessor}#{parentheses_range.source}"
    end
  end
  source << ".#{query_method}"
end

#collection_accessorObject



82
83
84
85
86
87
88
# File 'lib/transpec/syntax/have.rb', line 82

def collection_accessor
  if runtime_subject_data && runtime_subject_data[:collection_accessor].result
    runtime_subject_data[:collection_accessor].result.to_sym
  else
    items_name
  end
end

#collection_accessor_is_private?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'lib/transpec/syntax/have.rb', line 95

def collection_accessor_is_private?
  runtime_subject_data && runtime_subject_data[:collection_accessor_is_private?].result
end

#convert_to_standard_expectation!(parenthesize_matcher_arg = true) ⇒ Object



45
46
47
48
49
50
# File 'lib/transpec/syntax/have.rb', line 45

def convert_to_standard_expectation!(parenthesize_matcher_arg = true)
  return if project_requires_collection_matcher?
  replace(@expectation.subject_range, replacement_subject_source) if explicit_subject?
  replace(expression_range, replacement_matcher_source(parenthesize_matcher_arg))
  register_record if explicit_subject?
end

#default_query_methodObject



108
109
110
# File 'lib/transpec/syntax/have.rb', line 108

def default_query_method
  QUERY_METHOD_PRIORITIES.first
end

#explicit_subject?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/transpec/syntax/have.rb', line 52

def explicit_subject?
  @expectation.respond_to?(:subject_node)
end

#have_method_nameObject

rubocop:disable PredicateName



70
71
72
# File 'lib/transpec/syntax/have.rb', line 70

def have_method_name # rubocop:disable PredicateName
  have_node.children[1]
end

#have_nodeObject

rubocop:disable PredicateName



56
57
58
# File 'lib/transpec/syntax/have.rb', line 56

def have_node # rubocop:disable PredicateName
  node.children.first
end

#items_method_has_arguments?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/transpec/syntax/have.rb', line 66

def items_method_has_arguments?
  items_node.children.size > 2
end

#items_nameObject



74
75
76
# File 'lib/transpec/syntax/have.rb', line 74

def items_name
  items_node.children[1]
end

#project_requires_collection_matcher?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/transpec/syntax/have.rb', line 78

def project_requires_collection_matcher?
  runtime_subject_data && runtime_subject_data[:project_requires_collection_matcher?].result
end

#query_methodObject



99
100
101
102
103
104
105
106
# File 'lib/transpec/syntax/have.rb', line 99

def query_method
  if runtime_subject_data && runtime_subject_data[:available_query_methods]
    available_query_methods = runtime_subject_data[:available_query_methods].result
    (QUERY_METHOD_PRIORITIES & available_query_methods.map(&:to_sym)).first
  else
    default_query_method
  end
end

#replacement_matcher_source(parenthesize_arg) ⇒ Object



130
131
132
# File 'lib/transpec/syntax/have.rb', line 130

def replacement_matcher_source(parenthesize_arg)
  build_replacement_matcher_source(size_source, parenthesize_arg)
end

#replacement_subject_sourceObject



112
113
114
# File 'lib/transpec/syntax/have.rb', line 112

def replacement_subject_source
  build_replacement_subject_source(@expectation.subject_range.source)
end

#size_nodeObject



60
61
62
# File 'lib/transpec/syntax/have.rb', line 60

def size_node
  have_node.children[2]
end

#size_sourceObject



143
144
145
# File 'lib/transpec/syntax/have.rb', line 143

def size_source
  size_node.loc.expression.source
end

#subject_is_owner_of_collection?Boolean

Returns:

  • (Boolean)


90
91
92
93
# File 'lib/transpec/syntax/have.rb', line 90

def subject_is_owner_of_collection?
  return true if items_method_has_arguments?
  runtime_subject_data && !runtime_subject_data[:collection_accessor].result.nil?
end