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 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