sandwich 0.0.17 → 0.0.18

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