sandwich 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.11
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, parent|
18
- child.send("#{parent.class.name.underscore}=", parent)
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
 
@@ -1,20 +1,83 @@
1
1
  require 'strscan'
2
2
 
3
3
  module Sandwich
4
- module StringScannerExt
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.attr_separators
48
- @attr_separators = %w(with)
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
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 11
9
- version: 0.0.11
8
+ - 12
9
+ version: 0.0.12
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Leal