sandwich 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/sandwich/cucumber/model_steps.rb +9 -2
- data/lib/sandwich/model/base.rb +91 -38
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.12
|
@@ -14,8 +14,15 @@ Transform /the (.+?) "([^\"]*)"$/ do |what, value|
|
|
14
14
|
record(what, value)
|
15
15
|
end
|
16
16
|
|
17
|
-
Given /^(.+) belong(?:ing|s) to (.+)$/ do |child,
|
18
|
-
|
17
|
+
Given /^(.+) belong(?:ing|s) to (an?|the) (.+)$/ do |child, determiner, rest|
|
18
|
+
d = definition("#{determiner} #{rest}")
|
19
|
+
a = child.class.reflect_on_association(d.raw_model.underscore.to_sym)
|
20
|
+
|
21
|
+
raise "No association found for #{d.raw_model}" unless a
|
22
|
+
|
23
|
+
parent = materialize!("#{d.raw_determiner} #{a.class_name} #{d.raw_attributes}")
|
24
|
+
|
25
|
+
child.send("#{d.raw_model.underscore}=", parent)
|
19
26
|
child.save!
|
20
27
|
end
|
21
28
|
|
data/lib/sandwich/model/base.rb
CHANGED
@@ -1,20 +1,83 @@
|
|
1
1
|
require 'strscan'
|
2
2
|
|
3
3
|
module Sandwich
|
4
|
-
|
4
|
+
class DefinitionScanner < StringScanner
|
5
|
+
def initialize(str, attribute_separators)
|
6
|
+
super
|
7
|
+
@attribute_separators = attribute_separators
|
8
|
+
model_definition
|
9
|
+
end
|
10
|
+
|
11
|
+
def model_definition
|
12
|
+
@model_definition ||= [determiner, model, attributes]
|
13
|
+
end
|
14
|
+
|
15
|
+
def determiner
|
16
|
+
@determiner ||= begin
|
17
|
+
whitespace
|
18
|
+
scan(/(?:an?|\d+|the)/).tap { whitespace }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
alias_method :raw_determiner, :determiner
|
23
|
+
|
24
|
+
def model
|
25
|
+
@model ||= begin
|
26
|
+
whitespace
|
27
|
+
@model = if has_attribute_separator?
|
28
|
+
scan_until(/(?=\s+#{attribute_separators})/)
|
29
|
+
else
|
30
|
+
words
|
31
|
+
end.tap { whitespace }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :raw_model, :model
|
36
|
+
|
37
|
+
# assumes the scan pointer is past the model name
|
38
|
+
def attributes
|
39
|
+
whitespace
|
40
|
+
|
41
|
+
@raw_attributes = rest.strip
|
42
|
+
|
43
|
+
if has_attribute_separator?
|
44
|
+
skip(/#{attribute_separators}/)
|
45
|
+
whitespace
|
46
|
+
|
47
|
+
attribute_pairs
|
48
|
+
else
|
49
|
+
attribute_value
|
50
|
+
end.tap { whitespace }
|
51
|
+
end
|
52
|
+
|
53
|
+
def raw_attributes
|
54
|
+
@raw_attributes
|
55
|
+
end
|
56
|
+
|
57
|
+
def attribute_separators
|
58
|
+
"(?:#{@attribute_separators.join('|')})"
|
59
|
+
end
|
60
|
+
|
5
61
|
def words
|
6
62
|
if w = scan(/\s*(?:\w+ ?)+/) then w.strip end
|
7
63
|
end
|
8
64
|
|
9
|
-
alias_method :model_name, :words
|
10
65
|
alias_method :attribute_name, :words
|
11
66
|
|
67
|
+
def whitespace
|
68
|
+
skip(/\s*/)
|
69
|
+
end
|
70
|
+
|
12
71
|
def attribute_value
|
13
72
|
skip(/\s*"/)
|
14
73
|
|
15
74
|
scan(/[^"]+/).tap { |val| skip(/(?:"|\s+)/) }
|
16
75
|
end
|
17
76
|
|
77
|
+
def has_attribute_separator?
|
78
|
+
check_until(/#{attribute_separators}/)
|
79
|
+
end
|
80
|
+
|
18
81
|
def attribute_pairs
|
19
82
|
result = []
|
20
83
|
|
@@ -27,10 +90,6 @@ module Sandwich
|
|
27
90
|
Hash[*result.flatten]
|
28
91
|
end
|
29
92
|
|
30
|
-
::StringScanner.send(:include, self)
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
93
|
def attribute_pair
|
35
94
|
w = attribute_name
|
36
95
|
v = attribute_value
|
@@ -44,41 +103,11 @@ module Sandwich
|
|
44
103
|
end
|
45
104
|
|
46
105
|
module Model
|
47
|
-
def self.
|
48
|
-
@
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.attr_sep_str
|
52
|
-
"(?:#{attr_separators.join('|')})"
|
106
|
+
def self.attribute_separators
|
107
|
+
@attribute_separators = %w(with)
|
53
108
|
end
|
54
109
|
|
55
110
|
module Base
|
56
|
-
def materialize!(match)
|
57
|
-
scanner = StringScanner.new(match)
|
58
|
-
|
59
|
-
determiner = scanner.scan(/(?:an?|\d+)/)
|
60
|
-
scanner.skip(/\s+/)
|
61
|
-
|
62
|
-
model, values = if scanner.check_until(/#{_model.attr_sep_str}/)
|
63
|
-
model = scanner.scan_until(/(?=\s+#{_model.attr_sep_str})/)
|
64
|
-
scanner.skip(/\s+#{_model.attr_sep_str}\s+/)
|
65
|
-
|
66
|
-
[model, scanner.attribute_pairs]
|
67
|
-
else
|
68
|
-
[scanner.model_name, scanner.attribute_value]
|
69
|
-
end
|
70
|
-
|
71
|
-
if determiner.to_i == 1
|
72
|
-
record!(model, values)
|
73
|
-
else
|
74
|
-
determiner.times.map { record!(model, values) }
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def _model
|
79
|
-
Sandwich::Model
|
80
|
-
end
|
81
|
-
|
82
111
|
module Extensions
|
83
112
|
def default_attribute(name = nil, &block)
|
84
113
|
if name
|
@@ -100,6 +129,30 @@ module Sandwich
|
|
100
129
|
end
|
101
130
|
end
|
102
131
|
end
|
132
|
+
|
133
|
+
def materialize!(match)
|
134
|
+
determiner, model, values = definition(match).model_definition
|
135
|
+
|
136
|
+
if creator?(determiner)
|
137
|
+
if determiner.to_i == 1
|
138
|
+
record!(model, values)
|
139
|
+
else
|
140
|
+
determiner.times.map { record!(model, values) }
|
141
|
+
end
|
142
|
+
else
|
143
|
+
record(model, values)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def definition(str)
|
148
|
+
DefinitionScanner.new(str, Sandwich::Model.attribute_separators)
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def creator?(determiner)
|
154
|
+
determiner =~ /(an?|\d+)/
|
155
|
+
end
|
103
156
|
end
|
104
157
|
end
|
105
158
|
end
|