veneer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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