sandwich 0.0.17 → 0.0.18

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.17
1
+ 0.0.18
@@ -18,7 +18,7 @@ Then /^show me the source for ([^\"]+)$/ do |selector|
18
18
  puts locate(selector_for(selector)).html
19
19
  end
20
20
 
21
- Then /^wait (\d+)$/ do |time|
21
+ Then /^(?:|I )wait (\d+)$/ do |time|
22
22
  sleep time.to_i
23
23
  end
24
24
 
@@ -0,0 +1,11 @@
1
+ Given /^(?:a|the) (.+) with the following content:$/ do |selector, content|
2
+ instance_variable_set("@#{ivar(selector)}", content)
3
+ end
4
+
5
+ Given /^"([^\"]*)" is "([^\"]*)" in the (.+)$/ do |var, val, selector|
6
+ instance_variable_get("@#{ivar(selector)}").gsub!(var, val)
7
+ end
8
+
9
+ def ivar(selector)
10
+ selector.underscore.downcase
11
+ end
@@ -5,7 +5,14 @@ Given /^((?:an?|the|\d+) .+)$/ do |target|
5
5
  when String
6
6
  raise %Q{Could not materialize "#{target}"}
7
7
  else
8
- target
8
+ target.tap do
9
+ case target
10
+ when Array
11
+ target.each(&:save!)
12
+ else
13
+ target.save!
14
+ end
15
+ end
9
16
  end
10
17
  end
11
18
 
@@ -14,7 +21,7 @@ Transform /(?:an?|\d+|the) .+/ do |match|
14
21
  end
15
22
 
16
23
  Given /^(an?|the|\d+) (.+) with the following attributes:$/ do |total, what, table|
17
- total.times { record!(what, table.rows_hash) }
24
+ total.times { record!(what, table.rows_hash).save! }
18
25
  end
19
26
 
20
27
  Given /^(.+) belong(?:ing|s) to (an?|the) (.+)$/ do |child, determiner, rest|
@@ -24,22 +31,34 @@ Given /^(.+) belong(?:ing|s) to (an?|the) (.+)$/ do |child, determiner, rest|
24
31
  raise "No association found for #{d.raw_model}" unless a
25
32
 
26
33
  parent = materialize!("#{d.raw_determiner} #{a.class_name} #{d.raw_attributes}")
27
-
34
+ parent.save!
35
+
28
36
  child.send("#{d.raw_model.underscore}=", parent)
29
37
  child.save!
30
38
  end
31
39
 
32
- Given /^(.+) has (.+)$/ do |parent, child|
33
- case child
34
- when Array
35
- child.each { |c| parent.send(child.first.class.name.underscore.pluralize) << c }
40
+ Given /^(.+) has ((no|a|the|\d+) .+)$/ do |parent, child, determiner|
41
+ parent.save!
42
+
43
+ if determiner == "no"
44
+ d = definition(child)
45
+ a = parent.class.reflect_on_association(d.raw_model.underscore.to_sym)
46
+
47
+ raise "No association found for #{d.raw_model}" unless a
48
+
49
+ parent.send(d.raw_model).delete_all
36
50
  else
37
- parent.send(child.class.name.underscore.pluralize) << child
51
+ case child
52
+ when Array
53
+ child.each { |c| parent.send(child.first.class.name.underscore.pluralize) << c }
54
+ else
55
+ parent.send(child.class.name.underscore.pluralize) << child
56
+ end
38
57
  end
39
58
  end
40
59
 
41
60
  Given /^the following (.+):$/ do |what, table|
42
61
  model = what.singularize
43
62
 
44
- table.hashes.each { |h| record!(model, h) }
63
+ table.hashes.each { |h| record!(model, h).save! }
45
64
  end
@@ -12,6 +12,10 @@ When /^I follow "([^\"]*)"(?: (?:with)?in (.+))$/ do |link, container|
12
12
  inside(xpath(selector_for(container))) { click_link(link) }
13
13
  end
14
14
 
15
+ When /^I select "([^\"]*)" from (.+?)(?: (?:with)?in (.+))?$/ do |value, field_selector, container|
16
+ inside(xpath(container)) { select(value, :from => selector_for(field_selector)) }
17
+ end
18
+
15
19
  Then /^I should see "([^\"]*)" (?:with)?in (.+)$/ do |text, selector|
16
20
  page.should have_xpath(xpath(selector_for(selector)), :text => text)
17
21
  end
@@ -2,11 +2,11 @@ class String
2
2
  alias_method :super_to_i, :to_i
3
3
  alias_method :super_underscore, :underscore
4
4
 
5
- def to_i
5
+ def to_i(*args)
6
6
  case self
7
7
  when "a", "the", "an" then 1
8
8
  when "no" then 0
9
- else super_to_i
9
+ else super_to_i(*args)
10
10
  end
11
11
  end
12
12
 
@@ -1,6 +1,32 @@
1
1
  module Sandwich
2
2
  module Base
3
3
  module ClassMethods
4
+ def default_attribute(name = nil, &block)
5
+ if name
6
+ @default_attribute = name
7
+ elsif block_given?
8
+ @default_attribute = block
9
+ else
10
+ raise "Need an attribute name or a block for #{self}"
11
+ end
12
+ end
13
+
14
+ def default_attribute_args(value, op)
15
+ if @default_attribute.respond_to?(:call)
16
+ case @default_attribute.arity
17
+ when 1
18
+ @default_attribute.call(value)
19
+ when 2
20
+ @default_attribute.call(value, op)
21
+ else
22
+ raise ArgumentError, "the block sent to #{name}.default_attribute needs 1 or 2 arguments"
23
+ end
24
+ elsif @default_attribute
25
+ {@default_attribute => value}
26
+ else
27
+ raise "No default attribute defined for #{self}"
28
+ end
29
+ end
4
30
  end
5
31
  end
6
32
  end
@@ -1,144 +1,19 @@
1
- require 'strscan'
1
+ require 'sandwich/model/definition_scanner'
2
+ require 'sandwich/model/materializer'
2
3
 
3
4
  module Sandwich
4
5
  class ModelNotFoundError < StandardError; end
5
6
 
6
- class DefinitionScanner < StringScanner
7
- def initialize(str, attribute_separators)
8
- super
9
- @attribute_separators = attribute_separators
10
- model_definition
11
- end
12
-
13
- def model_definition
14
- @model_definition ||= [determiner, model, attributes]
15
- end
16
-
17
- def determiner
18
- @determiner ||= begin
19
- whitespace
20
- scan(/(?:an?|\d+|the)/).tap { whitespace }
21
- end
22
- end
23
-
24
- alias_method :raw_determiner, :determiner
25
-
26
- def model
27
- @model ||= begin
28
- whitespace
29
- @model = if has_attribute_separator?
30
- scan_until(/(?=\s+#{attribute_separators})/)
31
- else
32
- words
33
- end.tap { whitespace }
34
- end
35
- end
36
-
37
- alias_method :raw_model, :model
38
-
39
- # assumes the scan pointer is past the model name
40
- def attributes
41
- whitespace
42
-
43
- @raw_attributes = rest.strip
44
-
45
- if has_attribute_separator?
46
- skip(/#{attribute_separators}/)
47
- whitespace
48
-
49
- attribute_pairs
50
- else
51
- attribute_value
52
- end.tap { whitespace }
53
- end
54
-
55
- def raw_attributes
56
- @raw_attributes
57
- end
58
-
59
- def attribute_separators
60
- "(?:#{@attribute_separators.join('|')})"
61
- end
62
-
63
- def words
64
- if w = scan(/\s*(?:\w+ ?)+/) then w.strip end
65
- end
66
-
67
- alias_method :attribute_name, :words
68
-
69
- def whitespace
70
- skip(/\s*/)
71
- end
72
-
73
- def attribute_value
74
- skip(/\s*"/)
75
-
76
- scan(/[^"]+/).tap { |val| skip(/(?:"|\s+)/) }
77
- end
78
-
79
- def has_attribute_separator?
80
- check_until(/#{attribute_separators}/)
81
- end
82
-
83
- def attribute_pairs
84
- result = []
85
-
86
- while p = attribute_pair
87
- result << p
88
-
89
- scan(/\s*(?:and|,)\s*/)
90
- end
91
-
92
- Hash[*result.flatten]
93
- end
94
-
95
- def attribute_pair
96
- w = attribute_name
97
- v = attribute_value
98
-
99
- if w.nil? || v.nil?
100
- nil
101
- else
102
- [w, v]
103
- end
104
- end
105
- end
106
-
107
7
  module Model
108
8
  def self.attribute_separators
109
9
  @attribute_separators = %w(with)
110
10
  end
111
11
 
112
12
  module Base
113
- module Extensions
114
- def default_attribute(name = nil, &block)
115
- if name
116
- @default_attribute = name
117
- elsif block_given?
118
- @default_attribute = block
119
- else
120
- raise "Need an attribute name or a block for #{self}"
121
- end
122
- end
123
-
124
- def default_attribute_args(value, op)
125
- if @default_attribute.respond_to?(:call)
126
- case @default_attribute.arity
127
- when 1
128
- @default_attribute.call(value)
129
- when 2
130
- @default_attribute.call(value, op)
131
- else
132
- raise ArgumentError, "the block sent to #{name}.default_attribute needs 1 or 2 arguments"
133
- end
134
- elsif @default_attribute
135
- {@default_attribute => value}
136
- else
137
- raise "No default attribute defined for #{self}"
138
- end
139
- end
13
+ def Materializer(name)
14
+ Materializer[name]
140
15
  end
141
-
16
+
142
17
  def materialize!(match)
143
18
  determiner, model, values = definition(match).model_definition
144
19
 
@@ -161,6 +36,24 @@ module Sandwich
161
36
  DefinitionScanner.new(str, Sandwich::Model.attribute_separators)
162
37
  end
163
38
 
39
+ ##
40
+ # Create a record
41
+ def record!(name, args)
42
+ materializer = Materializer(name)
43
+
44
+ raise ModelNotFoundError, "No model found for '#{name}'" if materializer.nil?
45
+
46
+ materializer.new(args)
47
+ end
48
+
49
+ def record(name, args)
50
+ materializer = Materializer(name)
51
+
52
+ raise ModelNotFoundError, "No model found for '#{name}'" if materializer.nil?
53
+
54
+ materializer.get(args)
55
+ end
56
+
164
57
  private
165
58
 
166
59
  def creator?(determiner)
@@ -0,0 +1,106 @@
1
+ require 'strscan'
2
+
3
+ module Sandwich
4
+ module Model
5
+ class DefinitionScanner < StringScanner
6
+ def initialize(str, attribute_separators)
7
+ super
8
+ @attribute_separators = attribute_separators
9
+ model_definition
10
+ end
11
+
12
+ def model_definition
13
+ @model_definition ||= [determiner, model, attributes]
14
+ end
15
+
16
+ def determiner
17
+ @determiner ||= begin
18
+ whitespace
19
+ scan(/\b(?:an?|\d+|the|no)\b/).tap { whitespace }
20
+ end
21
+ end
22
+
23
+ alias_method :raw_determiner, :determiner
24
+
25
+ def model
26
+ @model ||= begin
27
+ whitespace
28
+ @model = if has_attribute_separator?
29
+ scan_until(/(?=\s+#{attribute_separators})/)
30
+ else
31
+ words
32
+ end.tap { whitespace }
33
+ end
34
+ end
35
+
36
+ alias_method :raw_model, :model
37
+
38
+ # assumes the scan pointer is past the model name
39
+ def attributes
40
+ whitespace
41
+
42
+ @raw_attributes = rest.strip
43
+
44
+ if has_attribute_separator?
45
+ skip(/#{attribute_separators}/)
46
+ whitespace
47
+
48
+ attribute_pairs
49
+ else
50
+ attribute_value
51
+ end.tap { whitespace }
52
+ end
53
+
54
+ def raw_attributes
55
+ @raw_attributes
56
+ end
57
+
58
+ def attribute_separators
59
+ "(?:#{@attribute_separators.join('|')})"
60
+ end
61
+
62
+ def words
63
+ if w = scan(/\s*(?:\w+ ?)+/) then w.strip end
64
+ end
65
+
66
+ alias_method :attribute_name, :words
67
+
68
+ def whitespace
69
+ skip(/\s*/)
70
+ end
71
+
72
+ def attribute_value
73
+ skip(/\s*"/)
74
+
75
+ scan(/[^"]+/).tap { |val| skip(/(?:"|\s+)/) }
76
+ end
77
+
78
+ def has_attribute_separator?
79
+ check_until(/#{attribute_separators}/)
80
+ end
81
+
82
+ def attribute_pairs
83
+ result = []
84
+
85
+ while p = attribute_pair
86
+ result << p
87
+
88
+ scan(/\s*(?:and|,)\s*/)
89
+ end
90
+
91
+ Hash[*result.flatten]
92
+ end
93
+
94
+ def attribute_pair
95
+ w = attribute_name
96
+ v = attribute_value
97
+
98
+ if w.nil? || v.nil?
99
+ nil
100
+ else
101
+ [w, v]
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -5,115 +5,38 @@ module Sandwich
5
5
  module Machinist
6
6
  include Model::Base
7
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 = if (key.to_s == model.name.underscore)
37
- [:master, model]
38
- else
39
- [key, model]
40
- end
41
- end
42
-
43
- def get(args)
44
- @model.find(:first, :conditions => prepare_args(args, :find)).tap do |result|
45
- raise "Could not find model for args: #{args.inspect}" if result.nil?
46
- end
47
- end
48
-
49
- def create(args = nil)
50
- @model.make(@key, prepare_args(args, :create))
51
- end
52
-
53
- private
54
-
55
- def prepare_args(args, op)
56
- case args
57
- when Hash
58
- Hash[*args.each_pair.map { |k, v| [k.underscore, prepare_value(k, v)] }.flatten]
59
- when nil
60
- {}
61
- else
62
- @model.default_attribute_args(args, op)
63
- end
64
- end
65
-
66
- def prepare_value(key, value)
67
- if assoc = @model.reflect_on_association(key.to_sym)
68
- self.class[assoc.class_name].get(value)
69
- else
70
- value
71
- end
8
+ class Materializer < Sandwich::Model::Materializer
9
+ def new(args = nil)
10
+ @model.make_unsaved(@key, prepare_args(args, :create))
72
11
  end
73
12
  end
74
13
 
14
+ def Materializer(name)
15
+ Materializer[name]
16
+ end
17
+
75
18
  module Extensions
76
19
  include Sandwich::Model::Base::Extensions
77
20
 
78
21
  def blueprint(name = :master, &blueprints)
79
22
  if block_given?
80
- m = Sandwich::Model::Machinist::Materializer
81
- m[name == :master ? self.name.underscore : name] = self
23
+ Machinist::Materializer[self.name.underscore] = self unless name == :master
82
24
  end
83
25
 
84
26
  super
85
27
  end
86
28
  end
87
-
88
-
89
- ##
90
- # Create a record
91
- def record!(name, args)
92
- materializer = Materializer[name]
93
-
94
- raise ModelNotFoundError, "No model found for '#{name}'" if materializer.nil?
95
-
96
- materializer.create(args)
97
- end
98
-
99
- def record(name, args)
100
- materializer = Materializer[name]
101
-
102
- raise ModelNotFoundError, "No model found for '#{name}'" if materializer.nil?
103
-
104
- materializer.get(args)
105
- end
106
29
  end
107
30
  end
108
31
  end
109
32
 
110
33
  if defined?(ActiveRecord::Base)
111
34
  require 'machinist/active_record'
35
+ require 'machinist/object'
112
36
 
113
37
  ActiveRecord::Base.send(:extend, Sandwich::Model::Machinist::Extensions)
114
38
  else
115
39
  raise "Don't know which machinist adapter to use."
116
40
  end
117
41
 
118
-
119
42
  World(Sandwich::Model::Machinist)
@@ -0,0 +1,67 @@
1
+ module Sandwich
2
+ module Model
3
+ class Materializer
4
+ def self.named_fixtures
5
+ @named_fixtures ||= {}
6
+ end
7
+
8
+ def self.[](key)
9
+ key = prepare_key(key)
10
+ key_s = key.to_s
11
+
12
+ if model = named_fixtures[key]
13
+ new(key, model)
14
+ else
15
+ new(key, key_s.classify.constantize) rescue nil
16
+ end
17
+ end
18
+
19
+ def self.[]=(key, value)
20
+ key = prepare_key(key)
21
+
22
+ raise "Named fixture '#{key}' already exists for class #{self[key]}" if self[key]
23
+
24
+ named_fixtures[key] = value
25
+ end
26
+
27
+ def self.prepare_key(key)
28
+ key.to_s.underscore.to_sym
29
+ end
30
+
31
+ def initialize(key, model)
32
+ @key, @model = if (key.to_s == model.name.underscore)
33
+ [:master, model]
34
+ else
35
+ [key, model]
36
+ end
37
+ end
38
+
39
+ def get(args)
40
+ @model.find(:first, :conditions => prepare_args(args, :find)).tap do |result|
41
+ raise "Could not find model for args: #{args.inspect}" if result.nil?
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def prepare_args(args, op)
48
+ case args
49
+ when Hash
50
+ Hash[*args.each_pair.map { |k, v| [k.underscore, prepare_value(k, v)] }.flatten]
51
+ when nil
52
+ {}
53
+ else
54
+ @model.default_attribute_args(args, op)
55
+ end
56
+ end
57
+
58
+ def prepare_value(key, value)
59
+ if assoc = @model.reflect_on_association(key.to_sym)
60
+ self.class[assoc.class_name].get(value)
61
+ else
62
+ value
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 17
9
- version: 0.0.17
8
+ - 18
9
+ version: 0.0.18
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-05-20 00:00:00 +01:00
17
+ date: 2010-06-02 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -97,6 +97,7 @@ files:
97
97
  - VERSION
98
98
  - lib/sandwich.rb
99
99
  - lib/sandwich/cucumber/debug_steps.rb
100
+ - lib/sandwich/cucumber/ivar_steps.rb
100
101
  - lib/sandwich/cucumber/model_steps.rb
101
102
  - lib/sandwich/cucumber/table_steps.rb
102
103
  - lib/sandwich/cucumber/time_steps.rb
@@ -111,7 +112,9 @@ files:
111
112
  - lib/sandwich/helpers/associations.rb
112
113
  - lib/sandwich/helpers/base.rb
113
114
  - lib/sandwich/model/base.rb
115
+ - lib/sandwich/model/definition_scanner.rb
114
116
  - lib/sandwich/model/machinist.rb
117
+ - lib/sandwich/model/materializer.rb
115
118
  - spec/sandwich_spec.rb
116
119
  - spec/spec.opts
117
120
  - spec/spec_helper.rb