sandwich 0.0.9 → 0.0.11

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.9
1
+ 0.0.11
@@ -1,35 +1,17 @@
1
1
  require 'sandwich/ext/string'
2
- require 'sandwich/cucumber/world'
3
2
 
4
- Given /^((?:an?|the|\d+) .+)$/ do |what|
5
- # la la la la
6
- end
7
-
8
- Transform /(an?|\d+) (.+) #{qc}$/ do |total, what, value|
9
- model = attr = nil
10
-
11
- begin
12
- model = class_for(what)
13
- attr = model.default_attribute
14
- rescue NameError
15
- what, attr = *what.split(/(?:with|in)/).map(&:strip)
16
- model = class_for(what)
17
- end
18
-
19
- raise "No attribute passed and no default attribute defined for #{model}" if attr.nil?
3
+ Given /^((?:an?|the|\d+) .+)$/ do |what| end
20
4
 
21
- r = total.times.map { model.make(attr.to_s.underscore => value) }
22
-
23
- r.length == 1 ? r.first : r
5
+ Transform /(?:an?|\d+) .+/ do |match|
6
+ materialize!(match)
24
7
  end
25
8
 
26
- Transform /the (.+) #{qc}$/ do |what, attr, value|
27
- class_for(what).find(:first, :conditions => {attr => value})
9
+ Given /^(an?|the|\d+) (.+) with the following attributes:$/ do |total, what, table|
10
+ total.times { record!(what, table.rows_hash) }
28
11
  end
29
12
 
30
- Transform /the (.+) #{qc}$/ do |what, value|
31
- klass = class_for(what)
32
- klass.find(:first, :conditions => {klass.default_attribute => value})
13
+ Transform /the (.+?) "([^\"]*)"$/ do |what, value|
14
+ record(what, value)
33
15
  end
34
16
 
35
17
  Given /^(.+) belong(?:ing|s) to (.+)$/ do |child, parent|
@@ -41,27 +23,8 @@ Given /^(.+) has (.+)$/ do |parent, child|
41
23
  parent.send(child.class.name.underscore.pluralize) << child
42
24
  end
43
25
 
44
- Given /^no (.+) exists?$/ do |what|
45
- class_for(what).delete_all
46
- end
47
-
48
- Given /^no (.+) (?:with|in) (.+) #{qc} exists?$/ do |what, attr, value|
49
- class_for(what).delete_all
50
- end
51
-
52
- Given /^(an?|the|\d+) (.+) with the following attributes:$/ do |total, what, table|
53
- class_for(what).tap do |model|
54
- total.times do
55
- model.make(Hash[*table.raw.map { |k, v| [k.underscore, value_for(model, k, v)] }.flatten])
56
- end
57
- end
58
- end
59
-
60
26
  Given /^the following (.+):$/ do |what, table|
61
- class_for(what.singularize).tap do |model|
62
- table.hashes.each do |h|
63
- model.make(Hash[*h.each_pair.map { |(k, v)| [k.underscore, value_for(model, k, v)] }.flatten])
64
- end
65
- end
66
- end
27
+ model = what.singularize
67
28
 
29
+ table.hashes.each { |h| record!(model, h) }
30
+ end
@@ -1,18 +1,5 @@
1
1
  module Sandwich
2
2
  module World
3
- def class_for(name)
4
- name.underscore.classify.constantize
5
- end
6
-
7
- def value_for(model, attr, value)
8
- if assoc = model.reflect_on_association(attr.to_sym)
9
- assoc_class = assoc.class_name.constantize
10
- assoc_class.find_or_make(assoc_class.default_attribute_query(value))
11
- else
12
- value
13
- end
14
- end
15
-
16
3
  def xpath(unknown_selector)
17
4
  kind, selector = if Array === unknown_selector
18
5
  [unknown_selector[0].to_sym, unknown_selector[1]]
@@ -1,17 +1,6 @@
1
1
  module Sandwich
2
2
  module Base
3
3
  module ClassMethods
4
- def default_attribute(name = nil)
5
- if name
6
- @default_attribute = name
7
- else
8
- @default_attribute or raise "No default attribute defined for #{self}"
9
- end
10
- end
11
-
12
- def default_attribute_query(value)
13
- {default_attribute => value}
14
- end
15
4
  end
16
5
  end
17
6
  end
@@ -0,0 +1,106 @@
1
+ require 'strscan'
2
+
3
+ module Sandwich
4
+ module StringScannerExt
5
+ def words
6
+ if w = scan(/\s*(?:\w+ ?)+/) then w.strip end
7
+ end
8
+
9
+ alias_method :model_name, :words
10
+ alias_method :attribute_name, :words
11
+
12
+ def attribute_value
13
+ skip(/\s*"/)
14
+
15
+ scan(/[^"]+/).tap { |val| skip(/(?:"|\s+)/) }
16
+ end
17
+
18
+ def attribute_pairs
19
+ result = []
20
+
21
+ while p = attribute_pair
22
+ result << p
23
+
24
+ scan(/\s*(?:and|,)\s*/)
25
+ end
26
+
27
+ Hash[*result.flatten]
28
+ end
29
+
30
+ ::StringScanner.send(:include, self)
31
+
32
+ private
33
+
34
+ def attribute_pair
35
+ w = attribute_name
36
+ v = attribute_value
37
+
38
+ if w.nil? || v.nil?
39
+ nil
40
+ else
41
+ [w, v]
42
+ end
43
+ end
44
+ end
45
+
46
+ 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('|')})"
53
+ end
54
+
55
+ 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
+ module Extensions
83
+ def default_attribute(name = nil, &block)
84
+ if name
85
+ @default_attribute = name
86
+ elsif block_given?
87
+ @default_attribute = block
88
+ else
89
+ raise "Need an attribute name or a block for #{self}"
90
+ end
91
+ end
92
+
93
+ def default_attribute_args(value, op)
94
+ if @default_attribute.respond_to?(:call)
95
+ @default_attribute.call(value, op)
96
+ elsif @default_attribute
97
+ {@default_attribute => value}
98
+ else
99
+ raise "No default attribute defined for #{self}"
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+
@@ -0,0 +1,131 @@
1
+ require 'sandwich/model/base'
2
+
3
+ module Sandwich
4
+ module Model
5
+ module Machinist
6
+ include Model::Base
7
+
8
+ class Materializer
9
+ def self.named_fixtures
10
+ @named_fixtures ||= {}
11
+ end
12
+
13
+ def self.[](key)
14
+ key = prepare_key(key)
15
+
16
+ if model = named_fixtures[key]
17
+ new(key, model)
18
+ else
19
+ nil
20
+ end
21
+ end
22
+
23
+ def self.[]=(key, value)
24
+ key = prepare_key(key)
25
+
26
+ raise "Named fixture '#{key}' already exists for class #{self[key]}" if self[key]
27
+
28
+ named_fixtures[key] = value
29
+ end
30
+
31
+ def self.prepare_key(key)
32
+ key.to_s.underscore.to_sym
33
+ end
34
+
35
+ def initialize(key, model)
36
+ @key, @model = key, model
37
+ end
38
+
39
+ def get(args)
40
+ args = prepare_args(args)
41
+
42
+ result = case args
43
+ when Hash
44
+ @model.find(:first, :conditions => args)
45
+ else
46
+ @model.find(:first, :conditions => @model.default_attribute_args(args, :find))
47
+ end
48
+
49
+ raise "Could not find model for args: #{args.inspect}" if result.nil?
50
+
51
+ result
52
+ end
53
+
54
+ def create(args = nil)
55
+ args = prepare_args(args)
56
+
57
+ case args
58
+ when Hash
59
+ @model.make(@key, args)
60
+ else
61
+ @model.make(@key, @model.default_attribute_args(args, :create))
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def prepare_args(args)
68
+ case args
69
+ when Hash
70
+ Hash[*args.each_pair.map { |k, v| [k.underscore, prepare_value(k, v)] }.flatten]
71
+ when nil
72
+ {}
73
+ else
74
+ args
75
+ end
76
+ end
77
+
78
+ def prepare_value(key, value)
79
+ if assoc = @model.reflect_on_association(key.to_sym)
80
+ self.class[assoc.class_name].get(value)
81
+ else
82
+ value
83
+ end
84
+ end
85
+ end
86
+
87
+ module Extensions
88
+ include Sandwich::Model::Base::Extensions
89
+
90
+ def blueprint(name = :master, &blueprints)
91
+ if block_given?
92
+ m = Sandwich::Model::Machinist::Materializer
93
+ m[name == :master ? self.name.underscore : name] = self
94
+ end
95
+
96
+ super
97
+ end
98
+ end
99
+
100
+
101
+ ##
102
+ # Create a record
103
+ def record!(name, args)
104
+ materializer = Materializer[name]
105
+
106
+ return name if materializer.nil?
107
+
108
+ materializer.create(args)
109
+ end
110
+
111
+ def record(name, args)
112
+ materializer = Materializer[name]
113
+
114
+ return name if materializer.nil?
115
+
116
+ materializer.get(args)
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ if defined?(ActiveRecord::Base)
123
+ require 'machinist/active_record'
124
+
125
+ ActiveRecord::Base.send(:extend, Sandwich::Model::Machinist::Extensions)
126
+ else
127
+ raise "Don't know which machinist adapter to use."
128
+ end
129
+
130
+
131
+ World(Sandwich::Model::Machinist)
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 9
9
- version: 0.0.9
8
+ - 11
9
+ version: 0.0.11
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Leal
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-29 00:00:00 +01:00
17
+ date: 2010-05-06 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -110,6 +110,8 @@ files:
110
110
  - lib/sandwich/helpers/amounts.rb
111
111
  - lib/sandwich/helpers/associations.rb
112
112
  - lib/sandwich/helpers/base.rb
113
+ - lib/sandwich/model/base.rb
114
+ - lib/sandwich/model/machinist.rb
113
115
  - spec/sandwich_spec.rb
114
116
  - spec/spec.opts
115
117
  - spec/spec_helper.rb