/
matchers.rb
105 lines (84 loc) · 2.88 KB
/
matchers.rb
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
module Pickle
class Parser
# Methods which return Regexps for matching and capturing various pickle expressions.
#
# Optionally, assigning a the Pickle::Config object to #config, to make the matchers
# aware of the config.
module Matchers
attr_accessor :config
delegate :predicates, :to => :config, :allow_nil => true
# generate an expression to capture a reference to a model
# @arguments to restrict the expression to the given factory names
# @return Regexp
def pickle_ref(*restrict_to)
/(#{match_pickle_ref(*restrict_to).source})/
end
# generate an expression to capture a plural factory name, such as 'users', 'admin users'
def pickle_plural
/(#{match_plural_factory.source})/
end
# generate an expression to capture a fields string suitable for pickle
def pickle_fields
/(#{match_fields.source})/
end
# generate an expression to capture a predicate, suitable for passing to Pickle::MakeMatcher#make_matcher
def pickle_predicate
/(#{match_predicate.source})/
end
protected
def match_disjunction(*strings)
/(?:#{strings.compact.join('|')})/
end
def match_quoted
/(?:"[^\"]*")/
end
def match_factory
match_disjunction('(?:\w|::\w){2,}', *factories)
end
def match_plural_factory
match_disjunction('\w\w+', *plural_factories)
end
def match_prefix
/(?:a|an|another|the|that)/
end
def match_ordinal
/\d+(?:st|nd|rd|th)/
end
def match_index_word
/(?:first|last|#{match_ordinal.source})/
end
def match_index
/(?:(?:the )?#{match_index_word.source})/
end
def match_field
/(?:\w+\: [^,]+(?=$|,))/
end
def match_fields
/#{match_field.source}(?:, #{match_field.source})*/
end
def match_predicate
predicates ? match_disjunction(*(predicates + [match_quoted])) : match_quoted
end
def match_model(*restrict_to)
factory = restrict_to.any? ? match_disjunction(*restrict_to) : match_factory
/(?:(?:#{match_index.source} |#{match_prefix.source} )?#{factory.source}(?:(?: |: )#{match_quoted.source})?)/
end
def match_pickle_ref(*restrict_to)
if mappings && restrict_to.empty?
/(?:#{match_disjunction(mappings).source}|#{match_quoted.source}|#{match_model.source})/
else
/(?:#{match_quoted.source}|#{match_model(*restrict_to).source})/
end
end
def mappings
config && config.mappings.map(&:search)
end
def factories
config && (config.factories | config.aliases.keys)
end
def plural_factories
config && factories.map(&:pluralize)
end
end
end
end