veneer 0.1.0

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.
Files changed (39) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.textile +138 -0
  5. data/Rakefile +64 -0
  6. data/VERSION +1 -0
  7. data/datamapper_setup.rb +2 -0
  8. data/lib/veneer.rb +35 -0
  9. data/lib/veneer/adapters/activerecord.rb +2 -0
  10. data/lib/veneer/adapters/activerecord/class_wrapper.rb +90 -0
  11. data/lib/veneer/adapters/activerecord/instance_wrapper.rb +11 -0
  12. data/lib/veneer/adapters/datamapper.rb +2 -0
  13. data/lib/veneer/adapters/datamapper/class_wrapper.rb +54 -0
  14. data/lib/veneer/adapters/datamapper/instance_wrapper.rb +23 -0
  15. data/lib/veneer/base/class_wrapper.rb +53 -0
  16. data/lib/veneer/base/conditional.rb +77 -0
  17. data/lib/veneer/base/instance_wrapper.rb +38 -0
  18. data/lib/veneer/core_ext/kernel.rb +17 -0
  19. data/lib/veneer/errors.rb +9 -0
  20. data/lib/veneer/proxy.rb +4 -0
  21. data/test/macros/class_wrapper/create_macro.rb +54 -0
  22. data/test/macros/class_wrapper/delete_macro.rb +31 -0
  23. data/test/macros/class_wrapper/find_macro.rb +112 -0
  24. data/test/macros/instance_wrapper/destroy_macro.rb +36 -0
  25. data/test/macros/instance_wrapper/new_record_macro.rb +35 -0
  26. data/test/macros/instance_wrapper/save_macro.rb +55 -0
  27. data/test/macros/veneer_constants_interface.rb +26 -0
  28. data/test/support/helpers.rb +18 -0
  29. data/test/test_helper.rb +16 -0
  30. data/test/veneer/adapters/active_record/active_record_setup.rb +28 -0
  31. data/test/veneer/adapters/active_record/class_wrapper_test.rb +21 -0
  32. data/test/veneer/adapters/active_record/instance_wrapper_test.rb +21 -0
  33. data/test/veneer/adapters/datamapper/class_wrapper_test.rb +22 -0
  34. data/test/veneer/adapters/datamapper/datamapper_setup.rb +25 -0
  35. data/test/veneer/adapters/datamapper/instance_wrapper_test.rb +21 -0
  36. data/test/veneer/base/conditonal_test.rb +118 -0
  37. data/test/veneer/proxy_test.rb +190 -0
  38. data/veneer.gemspec +95 -0
  39. metadata +109 -0
@@ -0,0 +1,35 @@
1
+ class Test::Unit::TestCase
2
+ def self.veneer_should_implement_new_record?
3
+ context "on an instance" do
4
+ should "setup the test correctly" do
5
+ assert_not_nil @klass
6
+ assert_kind_of Class, @klass
7
+ assert_not_nil @valid_attributes
8
+ assert_kind_of Hash, @valid_attributes
9
+ assert_kind_of Hash, @invalid_attributes
10
+ end
11
+
12
+ setup do
13
+ @instance = Veneer(@klass).new(@valid_attributes)
14
+ end
15
+
16
+ context "new_record" do
17
+ should "return true when the record is new" do
18
+ assert @instance.new_record?
19
+ end
20
+
21
+ should "return false when the record is successfully saved" do
22
+ assert @instance.save
23
+ assert !@instance.new_record?
24
+ end
25
+
26
+ should "return true if the record cannot be saved" do
27
+ v = Veneer(@klass).new(@invalid_attributes)
28
+ assert v.new_record?
29
+ assert !v.save
30
+ assert v.new_record?
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,55 @@
1
+ class Test::Unit::TestCase
2
+ def self.veneer_should_implement_save
3
+ context "on an instance" do
4
+ should "setup the test correctly" do
5
+ assert_not_nil @klass
6
+ assert_kind_of Class, @klass
7
+ assert_not_nil @valid_attributes
8
+ assert_kind_of Hash, @valid_attributes
9
+ assert_kind_of Hash, @invalid_attributes
10
+ end
11
+
12
+ setup do
13
+ @invalid = Veneer(@klass).new(@invalid_attributes)
14
+ @valid = Veneer(@klass).new(@valid_attributes)
15
+ end
16
+
17
+ context "save" do
18
+ should "return true when it can save" do
19
+ assert @valid.save
20
+ end
21
+
22
+ should "return false when it can't save" do
23
+ assert !@invalid.save
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.veneer_should_implement_save!
30
+ context "save!" do
31
+ should "setup the test correctly" do
32
+ assert_not_nil @klass
33
+ assert_kind_of Class, @klass
34
+ assert_not_nil @valid_attributes
35
+ assert_kind_of Hash, @valid_attributes
36
+ assert_kind_of Hash, @invalid_attributes
37
+ end
38
+
39
+ setup do
40
+ @invalid = Veneer(@klass).new(@invalid_attributes)
41
+ @valid = Veneer(@klass).new(@valid_attributes)
42
+ end
43
+
44
+ should "return true when successful" do
45
+ assert @valid.save!
46
+ end
47
+
48
+ should "raise Veneer::Errors::NotSaved when fails to save!" do
49
+ assert_raises Veneer::Errors::NotSaved do
50
+ @invalid.save!
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,26 @@
1
+ class Test::Unit::TestCase
2
+ def self.veneer_should_have_the_required_veneer_constants
3
+ context "required constants" do
4
+
5
+ should "have correctly setup the spec" do
6
+ assert_kind_of Class, @klass
7
+ end
8
+
9
+ should "have a VeneerInterface constant" do
10
+ assert_nothing_raised do
11
+ @klass::VeneerInterface
12
+ end
13
+ end
14
+
15
+ should "have a VeneerInterface::ClassWrapper" do
16
+ assert_nothing_raised do
17
+ @klass::VeneerInterface::ClassWrapper
18
+ end
19
+ end
20
+
21
+ should "inherit the class wrapper from the base class wrapper" do
22
+ assert_contains @klass::VeneerInterface::ClassWrapper.ancestors, ::Veneer::Base::ClassWrapper
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ module Veneer
2
+ module Test
3
+ module Helpers
4
+
5
+ def clear_constants!(*args)
6
+ Object.class_eval do
7
+ args.each do |obj|
8
+ begin
9
+ remove_const(obj)
10
+ rescue
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ end # Helpers
17
+ end # Test
18
+ end # Veneer
@@ -0,0 +1,16 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ Dir[File.join(File.dirname(__FILE__), "support", "**/*.rb")].each{|f| require f}
6
+ Dir[File.join(File.dirname(__FILE__), "macros", "**/*.rb")].each{|f| require f}
7
+
8
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
9
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
10
+ require 'veneer'
11
+
12
+ class Test::Unit::TestCase
13
+ include Veneer::Test::Helpers
14
+ end
15
+
16
+
@@ -0,0 +1,28 @@
1
+ require 'activerecord'
2
+ require 'veneer/adapters/activerecord'
3
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
4
+
5
+ class CreateActiveRecordFoo < ActiveRecord::Migration
6
+ def self.up
7
+ create_table :active_record_foos, :force => true do |t|
8
+ t.string :name
9
+ t.integer :order_field1
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :active_record_foos
15
+ end
16
+ end
17
+
18
+ CreateActiveRecordFoo.up
19
+
20
+ class ActiveRecordFoo < ActiveRecord::Base
21
+ def self.veneer_spec_reset!
22
+ delete_all
23
+ end
24
+
25
+ def validate
26
+ errors.add(:name, "Name cannot be 'invalid'") if name == "invalid"
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "..", "test_helper")
2
+ require File.join(File.dirname(__FILE__), "active_record_setup")
3
+
4
+ module Veneer
5
+ module Test
6
+ class ActiveRecordClassWrapper < ::Test::Unit::TestCase
7
+ context "Active Record Veneer Adapter" do
8
+ setup do
9
+ @klass = ::ActiveRecordFoo
10
+ @valid_attributes = {:name => "foo"}
11
+ @invalid_attributes = {:name => "invalid"}
12
+ end
13
+ veneer_should_have_the_required_veneer_constants
14
+ veneer_should_implement_create_with_valid_attributes
15
+ veneer_should_impelement_destroy_all
16
+ veneer_should_implement_create_with_invalid_attributes
17
+ veneer_should_implement_find
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "..", "test_helper")
2
+ require File.join(File.dirname(__FILE__), "active_record_setup")
3
+
4
+ module Veneer
5
+ module Test
6
+ class ActiveRecordInstanceWrapper < ::Test::Unit::TestCase
7
+ context "Active Record Veneer Adapter" do
8
+ setup do
9
+ @klass = ::ActiveRecordFoo
10
+ @valid_attributes = {:name => "foo"}
11
+ @invalid_attributes = {:name => "invalid"}
12
+ end
13
+
14
+ veneer_should_implement_new_record?
15
+ veneer_should_implement_save
16
+ veneer_should_implement_save!
17
+ veneer_should_implement_destroy
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "..", "test_helper")
2
+ require File.join(File.dirname(__FILE__), "datamapper_setup")
3
+
4
+ module Veneer
5
+ module Test
6
+ class DataMapperClassWrapper < ::Test::Unit::TestCase
7
+ context "DataMapper Veneer Adapter" do
8
+ setup do
9
+ @klass = DMFoo
10
+ @valid_attributes = {:name => "foo"}
11
+ @invalid_attributes = {:name => "invalid"}
12
+ end
13
+
14
+ veneer_should_have_the_required_veneer_constants
15
+ veneer_should_implement_create_with_valid_attributes
16
+ veneer_should_impelement_destroy_all
17
+ veneer_should_implement_create_with_invalid_attributes
18
+ veneer_should_implement_find
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ require 'dm-core'
2
+ require 'dm-validations'
3
+ require 'veneer/adapters/datamapper'
4
+
5
+ DataMapper.setup(:default, 'sqlite3::memory:')
6
+
7
+ class DMFoo
8
+ include DataMapper::Resource
9
+
10
+ property :id, Serial
11
+ property :name, String
12
+ property :order_field1, Integer
13
+
14
+ validates_with_method :name, :method => :check_name
15
+
16
+ def check_name
17
+ if name == "invalid"
18
+ [false, "Invalid name"]
19
+ else
20
+ true
21
+ end
22
+ end
23
+ end
24
+
25
+ DataMapper.auto_migrate!
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "..", "test_helper")
2
+ require File.join(File.dirname(__FILE__), "datamapper_setup")
3
+
4
+ module Veneer
5
+ module Test
6
+ class DataMapperInstanceWrapper < ::Test::Unit::TestCase
7
+ context "DataMapper Veneer Adapter" do
8
+ setup do
9
+ @klass = DMFoo
10
+ @valid_attributes = {:name => "foo"}
11
+ @invalid_attributes = {:name => "invalid"}
12
+ end
13
+
14
+ veneer_should_implement_new_record?
15
+ veneer_should_implement_save
16
+ veneer_should_implement_save!
17
+ veneer_should_implement_destroy
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,118 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper")
2
+
3
+ class VeneerBaseConditionalTest < Test::Unit::TestCase
4
+ context "Conditional from hash" do
5
+ should "create a conditonal object from a blank hash" do
6
+ c = Veneer::Conditional.from_hash({})
7
+ assert_instance_of Veneer::Conditional, c
8
+ end
9
+
10
+ should "create a conditional with a limit" do
11
+ c = Veneer::Conditional.from_hash(:limit => 5)
12
+ assert_equal c.limit, 5
13
+ end
14
+
15
+ should "have an offset specified" do
16
+ c = Veneer::Conditional.from_hash(:offset => 5)
17
+ assert_equal c.offset, 5
18
+ end
19
+
20
+ context "Veneer::Conditional::Order" do
21
+ should "let me specify a field" do
22
+ c = Veneer::Conditional::Order.new("foo")
23
+ assert_equal c.field, :foo
24
+ end
25
+
26
+ should "be decending in order by default" do
27
+ c = Veneer::Conditional::Order.new("foo")
28
+ assert_equal :desc, c.direction
29
+ end
30
+
31
+ should "let me specify an ascending order" do
32
+ c = Veneer::Conditional::Order.new("foo", "asc")
33
+ assert_equal :asc, c.direction
34
+ end
35
+
36
+ should "let me specify a decending order" do
37
+ ["desc", :desc].each do |dir|
38
+ c = Veneer::Conditional::Order.new("foo", dir)
39
+ assert_equal :desc, c.direction
40
+ end
41
+ end
42
+ end
43
+
44
+ should "have an order specified as an array" do
45
+ c = Veneer::Conditional.from_hash(:order => ["foo", "bar"])
46
+ conditionals = [:foo, :bar].map do |f|
47
+ Veneer::Conditional::Order.new(f)
48
+ end
49
+ assert_equal c.order.first, conditionals.first
50
+ assert_equal c.order.last, conditionals.last
51
+ end
52
+
53
+ should "let me specify the order with a direction" do
54
+ c = Veneer::Conditional.from_hash(:order => ["foo asc", "bar", "baz desc"])
55
+ conditionals = [[:foo, :asc], [:bar, :desc], [:baz, :desc]].map do |(f,d)|
56
+ Veneer::Conditional::Order.new(f, d)
57
+ end
58
+
59
+ (0..2).each do |i|
60
+ assert_equal c.order[i], conditionals[i]
61
+ end
62
+ end
63
+
64
+ context "conditions" do
65
+ context "condition object" do
66
+ should "let me specify an equal condition" do
67
+ c = Veneer::Conditional::Condition.new(:foo, "val", :eql)
68
+ assert_equal :foo, c.field
69
+ assert_equal :eql, c.operator
70
+ assert_equal "val", c.value
71
+ end
72
+ end
73
+
74
+ should "let me specify conditions" do
75
+ c = Veneer::Conditional.from_hash(:conditions => {:foo => "bar"})
76
+ condition = c.conditions.first
77
+ assert_instance_of Veneer::Conditional::Condition, condition
78
+ end
79
+
80
+ should "let me specify conditions for different operators" do
81
+ c = Veneer::Conditional.from_hash(:conditions => {
82
+ "foo not" => "bar",
83
+ "bar not" => 5,
84
+ "baz gte" => 6
85
+ })
86
+ foo = c.conditions.detect{|x| x.field == :foo}
87
+ assert_not_nil foo
88
+ assert_equal "bar", foo.value
89
+ assert_equal :not, foo.operator
90
+
91
+ bar = c.conditions.detect{|x| x.field == :bar}
92
+ assert_not_nil bar
93
+ assert_equal 5, bar.value
94
+ assert_equal :not, bar.operator
95
+
96
+ baz = c.conditions.detect{|x| x.field == :baz}
97
+ assert_not_nil baz
98
+ assert_equal 6, baz.value
99
+ assert_equal :gte, baz.operator
100
+ end
101
+
102
+ should "not error for valid operators" do
103
+ [:eql, :gt, :gte, :lt, :lte, :in, :not].each do |op|
104
+ assert_nothing_raised do
105
+ Veneer::Conditional::Condition.new(:foo, "bar", op)
106
+ end
107
+ end
108
+ end
109
+
110
+ should "error if the operator isn't valid" do
111
+ assert_raises Veneer::Errors::ConditionalOperatorNotSupported do
112
+ Veneer::Conditional::Condition.new(:foo, "bar", :not_real)
113
+ end
114
+ end
115
+ end
116
+
117
+ end
118
+ end
@@ -0,0 +1,190 @@
1
+ require File.join(File.dirname(__FILE__), "..", "test_helper")
2
+
3
+ class VeneerProxyTest < Test::Unit::TestCase
4
+ context "Veneer::Proxy" do
5
+ setup do
6
+ clear_constants! :Foo, :Bar
7
+
8
+ class ::Foo
9
+ attr_accessor :order_field1, :order_field2, :name
10
+ def self.veneer_spec_reset!
11
+ collection.clear
12
+ end
13
+
14
+ def self.collection
15
+ @collection ||= []
16
+ end
17
+
18
+ def initialize(opts = {})
19
+ @opts = opts
20
+ [:order_field1, :order_field2, :name].each do |f|
21
+ send(:"#{f}=", opts[f])
22
+ end
23
+ self.class.collection << self
24
+ @new_record = true
25
+ end
26
+
27
+ def new_record?
28
+ !!@new_record
29
+ end
30
+
31
+ def save
32
+ result = @opts[:invalid].nil?
33
+ @new_record = false if result
34
+ result
35
+ end
36
+
37
+ def save!
38
+ raise Veneer::Errors::NotSaved if @opts[:invalid]
39
+ @new_record = false
40
+ true
41
+ end
42
+
43
+
44
+ module VeneerInterface
45
+ class ClassWrapper < Veneer::Base::ClassWrapper
46
+ def new(opts)
47
+ ::Kernel.Veneer(klass.new(opts))
48
+ end
49
+
50
+ def destroy_all
51
+ klass.collection.clear
52
+ end
53
+
54
+ def find_first(conditional)
55
+ find_many(conditional).first
56
+ end
57
+
58
+ def find_many(conditional)
59
+ result = ::Foo.collection
60
+
61
+ unless conditional.order.empty?
62
+ order = conditional.order.first
63
+ result = result.sort_by{|i| i.send(order.field)}
64
+ result.reverse! if order.decending?
65
+ end
66
+
67
+ if conditional.offset
68
+ offset = conditional.offset.to_i
69
+ result = result[offset..-1]
70
+ end
71
+
72
+ conditional.conditions.each do |condition|
73
+ filtered = case condition.operator
74
+ when :eql
75
+ result.select{|i| i.send(condition.field) == condition.value}
76
+ when :not
77
+ result.select{|i| i.send(condition.field) != condition.value}
78
+ when :gt
79
+ result.select{|i| !i.send(condition.field).nil? && (i.send(condition.field) > condition.value)}
80
+ when :gte
81
+ result.select{|i| !i.send(condition.field).nil? && (i.send(condition.field) >= condition.value)}
82
+ when :lt
83
+ result.select{|i| !i.send(condition.field).nil? && (i.send(condition.field) < condition.value)}
84
+ when :lte
85
+ result.select{|i| !i.send(condition.field).nil? && (i.send(condition.field) <= condition.value)}
86
+ when :in
87
+ result.select{|i| condition.value.include?(i.send(condition.field))}
88
+ else
89
+ []
90
+ end
91
+ result = filtered.flatten.compact
92
+ end
93
+ if conditional.limit
94
+ result = result[0..(conditional.limit - 1)]
95
+ end
96
+ result
97
+ end
98
+
99
+ end
100
+
101
+ class InstanceWrapper < Veneer::Base::InstanceWrapper
102
+
103
+ def new_record?
104
+ instance.new_record?
105
+ end
106
+
107
+ def save!
108
+ instance.save!
109
+ end
110
+
111
+ def save
112
+ instance.save
113
+ rescue
114
+ false
115
+ end
116
+
117
+ def destroy
118
+ instance.class.collection.delete(instance)
119
+ self
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end # setup
125
+
126
+ should "be a BasicObject" do
127
+ assert_equal Veneer::Proxy.ancestors[1], BasicObject
128
+ end
129
+
130
+ context "test implementation" do
131
+ setup do
132
+ @klass = ::Foo
133
+ @valid_attributes = {:name => "foo"}
134
+ @invalid_attributes = {:invalid => true}
135
+ @instance = ::Foo.new
136
+ end
137
+
138
+ veneer_should_have_the_required_veneer_constants
139
+ veneer_should_implement_create_with_valid_attributes
140
+ veneer_should_implement_create_with_invalid_attributes
141
+ veneer_should_impelement_destroy_all
142
+ veneer_should_implement_find
143
+ veneer_should_implement_new_record?
144
+ veneer_should_implement_save
145
+ veneer_should_implement_save!
146
+ veneer_should_implement_destroy
147
+ end
148
+
149
+ context "all" do
150
+ setup do
151
+ ::Foo.collection.clear
152
+ (0..5).each do |i|
153
+ ::Foo.new(:name => "foo#{i}", :order_field1 => i)
154
+ end
155
+ end
156
+
157
+ teardown{ ::Foo.collection.clear }
158
+
159
+ should "get all the resources" do
160
+ assert_equal ::Foo.collection.size, Veneer(::Foo).all.size
161
+ end
162
+
163
+ should "get the resources with a condition" do
164
+ assert_equal 1, Veneer(::Foo).all(:conditions => {:name => "foo1"}).size
165
+ end
166
+
167
+ should "get the resources with offset, limit" do
168
+ result = Veneer(::Foo).all(:offset => 1, :limit => 3)
169
+ assert_equal 3, result.size
170
+ end
171
+ end
172
+
173
+ context "first" do
174
+ setup do
175
+ ::Foo.collection.clear
176
+ (0..5).each do |i|
177
+ ::Foo.new(:name => "foo#{i}", :order_field1 => i)
178
+ end
179
+ end
180
+
181
+ teardown{ ::Foo.collection.clear }
182
+
183
+ should "get the correct resource with equal" do
184
+ expected = ::Foo.collection.select{|i| i.name == "foo1"}.first
185
+ result = Veneer(::Foo).first(:conditions => {:name => "foo1"})
186
+ assert_equal expected, result.instance
187
+ end
188
+ end
189
+ end
190
+ end