viking-sequel 3.10.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.
- data/CHANGELOG +3134 -0
- data/COPYING +19 -0
- data/README.rdoc +723 -0
- data/Rakefile +193 -0
- data/bin/sequel +196 -0
- data/doc/advanced_associations.rdoc +644 -0
- data/doc/cheat_sheet.rdoc +218 -0
- data/doc/dataset_basics.rdoc +106 -0
- data/doc/dataset_filtering.rdoc +158 -0
- data/doc/opening_databases.rdoc +296 -0
- data/doc/prepared_statements.rdoc +104 -0
- data/doc/reflection.rdoc +84 -0
- data/doc/release_notes/1.0.txt +38 -0
- data/doc/release_notes/1.1.txt +143 -0
- data/doc/release_notes/1.3.txt +101 -0
- data/doc/release_notes/1.4.0.txt +53 -0
- data/doc/release_notes/1.5.0.txt +155 -0
- data/doc/release_notes/2.0.0.txt +298 -0
- data/doc/release_notes/2.1.0.txt +271 -0
- data/doc/release_notes/2.10.0.txt +328 -0
- data/doc/release_notes/2.11.0.txt +215 -0
- data/doc/release_notes/2.12.0.txt +534 -0
- data/doc/release_notes/2.2.0.txt +253 -0
- data/doc/release_notes/2.3.0.txt +88 -0
- data/doc/release_notes/2.4.0.txt +106 -0
- data/doc/release_notes/2.5.0.txt +137 -0
- data/doc/release_notes/2.6.0.txt +157 -0
- data/doc/release_notes/2.7.0.txt +166 -0
- data/doc/release_notes/2.8.0.txt +171 -0
- data/doc/release_notes/2.9.0.txt +97 -0
- data/doc/release_notes/3.0.0.txt +221 -0
- data/doc/release_notes/3.1.0.txt +406 -0
- data/doc/release_notes/3.10.0.txt +286 -0
- data/doc/release_notes/3.2.0.txt +268 -0
- data/doc/release_notes/3.3.0.txt +192 -0
- data/doc/release_notes/3.4.0.txt +325 -0
- data/doc/release_notes/3.5.0.txt +510 -0
- data/doc/release_notes/3.6.0.txt +366 -0
- data/doc/release_notes/3.7.0.txt +179 -0
- data/doc/release_notes/3.8.0.txt +151 -0
- data/doc/release_notes/3.9.0.txt +233 -0
- data/doc/schema.rdoc +36 -0
- data/doc/sharding.rdoc +113 -0
- data/doc/virtual_rows.rdoc +205 -0
- data/lib/sequel.rb +1 -0
- data/lib/sequel/adapters/ado.rb +90 -0
- data/lib/sequel/adapters/ado/mssql.rb +30 -0
- data/lib/sequel/adapters/amalgalite.rb +176 -0
- data/lib/sequel/adapters/db2.rb +139 -0
- data/lib/sequel/adapters/dbi.rb +113 -0
- data/lib/sequel/adapters/do.rb +188 -0
- data/lib/sequel/adapters/do/mysql.rb +49 -0
- data/lib/sequel/adapters/do/postgres.rb +91 -0
- data/lib/sequel/adapters/do/sqlite.rb +40 -0
- data/lib/sequel/adapters/firebird.rb +283 -0
- data/lib/sequel/adapters/informix.rb +77 -0
- data/lib/sequel/adapters/jdbc.rb +587 -0
- data/lib/sequel/adapters/jdbc/as400.rb +58 -0
- data/lib/sequel/adapters/jdbc/h2.rb +133 -0
- data/lib/sequel/adapters/jdbc/mssql.rb +57 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +78 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +50 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +108 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +55 -0
- data/lib/sequel/adapters/mysql.rb +421 -0
- data/lib/sequel/adapters/odbc.rb +143 -0
- data/lib/sequel/adapters/odbc/mssql.rb +42 -0
- data/lib/sequel/adapters/openbase.rb +64 -0
- data/lib/sequel/adapters/oracle.rb +131 -0
- data/lib/sequel/adapters/postgres.rb +504 -0
- data/lib/sequel/adapters/shared/mssql.rb +490 -0
- data/lib/sequel/adapters/shared/mysql.rb +498 -0
- data/lib/sequel/adapters/shared/oracle.rb +195 -0
- data/lib/sequel/adapters/shared/postgres.rb +830 -0
- data/lib/sequel/adapters/shared/progress.rb +44 -0
- data/lib/sequel/adapters/shared/sqlite.rb +389 -0
- data/lib/sequel/adapters/sqlite.rb +224 -0
- data/lib/sequel/adapters/utils/stored_procedures.rb +84 -0
- data/lib/sequel/connection_pool.rb +99 -0
- data/lib/sequel/connection_pool/sharded_single.rb +84 -0
- data/lib/sequel/connection_pool/sharded_threaded.rb +211 -0
- data/lib/sequel/connection_pool/single.rb +29 -0
- data/lib/sequel/connection_pool/threaded.rb +150 -0
- data/lib/sequel/core.rb +293 -0
- data/lib/sequel/core_sql.rb +241 -0
- data/lib/sequel/database.rb +1079 -0
- data/lib/sequel/database/schema_generator.rb +327 -0
- data/lib/sequel/database/schema_methods.rb +203 -0
- data/lib/sequel/database/schema_sql.rb +320 -0
- data/lib/sequel/dataset.rb +32 -0
- data/lib/sequel/dataset/actions.rb +441 -0
- data/lib/sequel/dataset/features.rb +86 -0
- data/lib/sequel/dataset/graph.rb +254 -0
- data/lib/sequel/dataset/misc.rb +119 -0
- data/lib/sequel/dataset/mutation.rb +64 -0
- data/lib/sequel/dataset/prepared_statements.rb +227 -0
- data/lib/sequel/dataset/query.rb +709 -0
- data/lib/sequel/dataset/sql.rb +996 -0
- data/lib/sequel/exceptions.rb +51 -0
- data/lib/sequel/extensions/blank.rb +43 -0
- data/lib/sequel/extensions/inflector.rb +242 -0
- data/lib/sequel/extensions/looser_typecasting.rb +21 -0
- data/lib/sequel/extensions/migration.rb +239 -0
- data/lib/sequel/extensions/named_timezones.rb +61 -0
- data/lib/sequel/extensions/pagination.rb +100 -0
- data/lib/sequel/extensions/pretty_table.rb +82 -0
- data/lib/sequel/extensions/query.rb +52 -0
- data/lib/sequel/extensions/schema_dumper.rb +271 -0
- data/lib/sequel/extensions/sql_expr.rb +122 -0
- data/lib/sequel/extensions/string_date_time.rb +46 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +48 -0
- data/lib/sequel/metaprogramming.rb +9 -0
- data/lib/sequel/model.rb +120 -0
- data/lib/sequel/model/associations.rb +1514 -0
- data/lib/sequel/model/base.rb +1069 -0
- data/lib/sequel/model/default_inflections.rb +45 -0
- data/lib/sequel/model/errors.rb +39 -0
- data/lib/sequel/model/exceptions.rb +21 -0
- data/lib/sequel/model/inflections.rb +162 -0
- data/lib/sequel/model/plugins.rb +70 -0
- data/lib/sequel/plugins/active_model.rb +59 -0
- data/lib/sequel/plugins/association_dependencies.rb +103 -0
- data/lib/sequel/plugins/association_proxies.rb +41 -0
- data/lib/sequel/plugins/boolean_readers.rb +53 -0
- data/lib/sequel/plugins/caching.rb +141 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +214 -0
- data/lib/sequel/plugins/composition.rb +138 -0
- data/lib/sequel/plugins/force_encoding.rb +72 -0
- data/lib/sequel/plugins/hook_class_methods.rb +126 -0
- data/lib/sequel/plugins/identity_map.rb +116 -0
- data/lib/sequel/plugins/instance_filters.rb +98 -0
- data/lib/sequel/plugins/instance_hooks.rb +57 -0
- data/lib/sequel/plugins/lazy_attributes.rb +77 -0
- data/lib/sequel/plugins/many_through_many.rb +208 -0
- data/lib/sequel/plugins/nested_attributes.rb +206 -0
- data/lib/sequel/plugins/optimistic_locking.rb +81 -0
- data/lib/sequel/plugins/rcte_tree.rb +281 -0
- data/lib/sequel/plugins/schema.rb +66 -0
- data/lib/sequel/plugins/serialization.rb +166 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +74 -0
- data/lib/sequel/plugins/subclasses.rb +45 -0
- data/lib/sequel/plugins/tactical_eager_loading.rb +61 -0
- data/lib/sequel/plugins/timestamps.rb +87 -0
- data/lib/sequel/plugins/touch.rb +118 -0
- data/lib/sequel/plugins/typecast_on_load.rb +72 -0
- data/lib/sequel/plugins/validation_class_methods.rb +405 -0
- data/lib/sequel/plugins/validation_helpers.rb +223 -0
- data/lib/sequel/sql.rb +1020 -0
- data/lib/sequel/timezones.rb +161 -0
- data/lib/sequel/version.rb +12 -0
- data/lib/sequel_core.rb +1 -0
- data/lib/sequel_model.rb +1 -0
- data/spec/adapters/firebird_spec.rb +407 -0
- data/spec/adapters/informix_spec.rb +97 -0
- data/spec/adapters/mssql_spec.rb +403 -0
- data/spec/adapters/mysql_spec.rb +1019 -0
- data/spec/adapters/oracle_spec.rb +286 -0
- data/spec/adapters/postgres_spec.rb +969 -0
- data/spec/adapters/spec_helper.rb +51 -0
- data/spec/adapters/sqlite_spec.rb +432 -0
- data/spec/core/connection_pool_spec.rb +808 -0
- data/spec/core/core_sql_spec.rb +417 -0
- data/spec/core/database_spec.rb +1662 -0
- data/spec/core/dataset_spec.rb +3827 -0
- data/spec/core/expression_filters_spec.rb +595 -0
- data/spec/core/object_graph_spec.rb +296 -0
- data/spec/core/schema_generator_spec.rb +159 -0
- data/spec/core/schema_spec.rb +830 -0
- data/spec/core/spec_helper.rb +56 -0
- data/spec/core/version_spec.rb +7 -0
- data/spec/extensions/active_model_spec.rb +76 -0
- data/spec/extensions/association_dependencies_spec.rb +127 -0
- data/spec/extensions/association_proxies_spec.rb +50 -0
- data/spec/extensions/blank_spec.rb +67 -0
- data/spec/extensions/boolean_readers_spec.rb +92 -0
- data/spec/extensions/caching_spec.rb +250 -0
- data/spec/extensions/class_table_inheritance_spec.rb +252 -0
- data/spec/extensions/composition_spec.rb +194 -0
- data/spec/extensions/force_encoding_spec.rb +117 -0
- data/spec/extensions/hook_class_methods_spec.rb +470 -0
- data/spec/extensions/identity_map_spec.rb +202 -0
- data/spec/extensions/inflector_spec.rb +181 -0
- data/spec/extensions/instance_filters_spec.rb +55 -0
- data/spec/extensions/instance_hooks_spec.rb +133 -0
- data/spec/extensions/lazy_attributes_spec.rb +153 -0
- data/spec/extensions/looser_typecasting_spec.rb +39 -0
- data/spec/extensions/many_through_many_spec.rb +884 -0
- data/spec/extensions/migration_spec.rb +332 -0
- data/spec/extensions/named_timezones_spec.rb +72 -0
- data/spec/extensions/nested_attributes_spec.rb +396 -0
- data/spec/extensions/optimistic_locking_spec.rb +100 -0
- data/spec/extensions/pagination_spec.rb +99 -0
- data/spec/extensions/pretty_table_spec.rb +91 -0
- data/spec/extensions/query_spec.rb +85 -0
- data/spec/extensions/rcte_tree_spec.rb +205 -0
- data/spec/extensions/schema_dumper_spec.rb +357 -0
- data/spec/extensions/schema_spec.rb +127 -0
- data/spec/extensions/serialization_spec.rb +209 -0
- data/spec/extensions/single_table_inheritance_spec.rb +96 -0
- data/spec/extensions/spec_helper.rb +91 -0
- data/spec/extensions/sql_expr_spec.rb +89 -0
- data/spec/extensions/string_date_time_spec.rb +93 -0
- data/spec/extensions/subclasses_spec.rb +52 -0
- data/spec/extensions/tactical_eager_loading_spec.rb +65 -0
- data/spec/extensions/thread_local_timezones_spec.rb +45 -0
- data/spec/extensions/timestamps_spec.rb +150 -0
- data/spec/extensions/touch_spec.rb +155 -0
- data/spec/extensions/typecast_on_load_spec.rb +69 -0
- data/spec/extensions/validation_class_methods_spec.rb +984 -0
- data/spec/extensions/validation_helpers_spec.rb +438 -0
- data/spec/integration/associations_test.rb +281 -0
- data/spec/integration/database_test.rb +26 -0
- data/spec/integration/dataset_test.rb +963 -0
- data/spec/integration/eager_loader_test.rb +734 -0
- data/spec/integration/model_test.rb +130 -0
- data/spec/integration/plugin_test.rb +814 -0
- data/spec/integration/prepared_statement_test.rb +213 -0
- data/spec/integration/schema_test.rb +361 -0
- data/spec/integration/spec_helper.rb +73 -0
- data/spec/integration/timezone_test.rb +55 -0
- data/spec/integration/transaction_test.rb +122 -0
- data/spec/integration/type_test.rb +96 -0
- data/spec/model/association_reflection_spec.rb +175 -0
- data/spec/model/associations_spec.rb +2633 -0
- data/spec/model/base_spec.rb +418 -0
- data/spec/model/dataset_methods_spec.rb +78 -0
- data/spec/model/eager_loading_spec.rb +1391 -0
- data/spec/model/hooks_spec.rb +240 -0
- data/spec/model/inflector_spec.rb +26 -0
- data/spec/model/model_spec.rb +593 -0
- data/spec/model/plugins_spec.rb +236 -0
- data/spec/model/record_spec.rb +1500 -0
- data/spec/model/spec_helper.rb +97 -0
- data/spec/model/validations_spec.rb +153 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec_config.rb.example +10 -0
- metadata +346 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
describe "Serialization plugin" do
|
7
|
+
before do
|
8
|
+
@c = Class.new(Sequel::Model(:items))
|
9
|
+
@c.plugin :composition
|
10
|
+
@c.columns :id, :year, :month, :day
|
11
|
+
@o = @c.load(:id=>1, :year=>1, :month=>2, :day=>3)
|
12
|
+
MODEL_DB.reset
|
13
|
+
end
|
14
|
+
|
15
|
+
it ".composition should add compositions" do
|
16
|
+
@o.should_not respond_to(:date)
|
17
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
18
|
+
@o.date.should == Date.new(1, 2, 3)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "loading the plugin twice should not remove existing compositions" do
|
22
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
23
|
+
@c.plugin :composition
|
24
|
+
@c.compositions.keys.should == [:date]
|
25
|
+
end
|
26
|
+
|
27
|
+
it ".composition should raise an error if :composer and :decomposer options are not present and :mapping option is not provided" do
|
28
|
+
proc{@c.composition :date}.should raise_error(Sequel::Error)
|
29
|
+
proc{@c.composition :date, :composer=>proc{}, :decomposer=>proc{}}.should_not raise_error
|
30
|
+
proc{@c.composition :date, :mapping=>[]}.should_not raise_error
|
31
|
+
end
|
32
|
+
|
33
|
+
it ".compositions should return the reflection hash of compositions" do
|
34
|
+
@c.compositions.should == {}
|
35
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
36
|
+
@c.compositions.keys.should == [:date]
|
37
|
+
r = @c.compositions.values.first
|
38
|
+
r[:mapping].should == [:year, :month, :day]
|
39
|
+
r[:composer].should be_a_kind_of(Proc)
|
40
|
+
r[:decomposer].should be_a_kind_of(Proc)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "#compositions should be a hash of cached values of compositions" do
|
44
|
+
@o.compositions.should == {}
|
45
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
46
|
+
@o.date
|
47
|
+
@o.compositions.should == {:date=>Date.new(1, 2, 3)}
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should work with custom :composer and :decomposer options" do
|
51
|
+
@c.composition :date, :composer=>proc{Date.new(year+1, month+2, day+3)}, :decomposer=>proc{[:year, :month, :day].each{|s| self.send("#{s}=", date.send(s) * 2)}}
|
52
|
+
@o.date.should == Date.new(2, 4, 6)
|
53
|
+
@o.save
|
54
|
+
MODEL_DB.sqls.last.should include("year = 4")
|
55
|
+
MODEL_DB.sqls.last.should include("month = 8")
|
56
|
+
MODEL_DB.sqls.last.should include("day = 12")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should allow call super in composition getter and setter method definition in class" do
|
60
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
61
|
+
@c.class_eval do
|
62
|
+
def date
|
63
|
+
super + 1
|
64
|
+
end
|
65
|
+
def date=(v)
|
66
|
+
super(v - 3)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
@o.date.should == Date.new(1, 2, 4)
|
70
|
+
@o.compositions[:date].should == Date.new(1, 2, 3)
|
71
|
+
@o.date = Date.new(1, 3, 5)
|
72
|
+
@o.compositions[:date].should == Date.new(1, 3, 2)
|
73
|
+
@o.date.should == Date.new(1, 3, 3)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should mark the object as modified whenever the composition is set" do
|
77
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
78
|
+
@o.modified?.should == false
|
79
|
+
@o.date = Date.new(3, 4, 5)
|
80
|
+
@o.modified?.should == true
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should only decompose existing compositions" do
|
84
|
+
called = false
|
85
|
+
@c.composition :date, :composer=>proc{}, :decomposer=>proc{called = true}
|
86
|
+
called.should == false
|
87
|
+
@o.save
|
88
|
+
called.should == false
|
89
|
+
@o.date = Date.new(1,2,3)
|
90
|
+
called.should == false
|
91
|
+
@o.save_changes
|
92
|
+
called.should == true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should clear compositions cache when reloading" do
|
96
|
+
@c.composition :date, :composer=>proc{}, :decomposer=>proc{called = true}
|
97
|
+
@o.date = Date.new(3, 4, 5)
|
98
|
+
@o.reload
|
99
|
+
@o.compositions.should == {}
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should instantiate compositions lazily" do
|
103
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
104
|
+
@o.compositions.should == {}
|
105
|
+
@o.date
|
106
|
+
@o.compositions.should == {:date=>Date.new(1,2,3)}
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should cache value of composition" do
|
110
|
+
times = 0
|
111
|
+
@c.composition :date, :composer=>proc{times+=1}, :decomposer=>proc{called = true}
|
112
|
+
times.should == 0
|
113
|
+
@o.date
|
114
|
+
times.should == 1
|
115
|
+
@o.date
|
116
|
+
times.should == 1
|
117
|
+
end
|
118
|
+
|
119
|
+
it ":class option should take an string, symbol, or class" do
|
120
|
+
@c.composition :date1, :class=>'Date', :mapping=>[:year, :month, :day]
|
121
|
+
@c.composition :date2, :class=>:Date, :mapping=>[:year, :month, :day]
|
122
|
+
@c.composition :date3, :class=>Date, :mapping=>[:year, :month, :day]
|
123
|
+
@o.date1.should == Date.new(1, 2, 3)
|
124
|
+
@o.date2.should == Date.new(1, 2, 3)
|
125
|
+
@o.date3.should == Date.new(1, 2, 3)
|
126
|
+
end
|
127
|
+
|
128
|
+
it ":mapping option should work with a single array of symbols" do
|
129
|
+
c = Class.new do
|
130
|
+
def initialize(y, m)
|
131
|
+
@y, @m = y, m
|
132
|
+
end
|
133
|
+
def year
|
134
|
+
@y * 2
|
135
|
+
end
|
136
|
+
def month
|
137
|
+
@m * 3
|
138
|
+
end
|
139
|
+
end
|
140
|
+
@c.composition :date, :class=>c, :mapping=>[:year, :month]
|
141
|
+
@o.date.year.should == 2
|
142
|
+
@o.date.month.should == 6
|
143
|
+
@o.date = c.new(3, 4)
|
144
|
+
@o.save
|
145
|
+
MODEL_DB.sqls.last.should include("year = 6")
|
146
|
+
MODEL_DB.sqls.last.should include("month = 12")
|
147
|
+
end
|
148
|
+
|
149
|
+
it ":mapping option should work with an array of two pairs of symbols" do
|
150
|
+
c = Class.new do
|
151
|
+
def initialize(y, m)
|
152
|
+
@y, @m = y, m
|
153
|
+
end
|
154
|
+
def y
|
155
|
+
@y * 2
|
156
|
+
end
|
157
|
+
def m
|
158
|
+
@m * 3
|
159
|
+
end
|
160
|
+
end
|
161
|
+
@c.composition :date, :class=>c, :mapping=>[[:year, :y], [:month, :m]]
|
162
|
+
@o.date.y.should == 2
|
163
|
+
@o.date.m.should == 6
|
164
|
+
@o.date = c.new(3, 4)
|
165
|
+
@o.save
|
166
|
+
MODEL_DB.sqls.last.should include("year = 6")
|
167
|
+
MODEL_DB.sqls.last.should include("month = 12")
|
168
|
+
end
|
169
|
+
|
170
|
+
it ":mapping option :composer should return nil if all values are nil" do
|
171
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
172
|
+
@c.new.date.should == nil
|
173
|
+
end
|
174
|
+
|
175
|
+
it ":mapping option :decomposer should set all related fields to nil if nil" do
|
176
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
177
|
+
@o.date = nil
|
178
|
+
@o.save
|
179
|
+
MODEL_DB.sqls.last.should include("year = NULL")
|
180
|
+
MODEL_DB.sqls.last.should include("month = NULL")
|
181
|
+
MODEL_DB.sqls.last.should include("day = NULL")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should work correctly with subclasses" do
|
185
|
+
@c.composition :date, :mapping=>[:year, :month, :day]
|
186
|
+
c = Class.new(@c)
|
187
|
+
o = c.load(:id=>1, :year=>1, :month=>2, :day=>3)
|
188
|
+
o.date.should == Date.new(1, 2, 3)
|
189
|
+
o.save
|
190
|
+
MODEL_DB.sqls.last.should include("year = 1")
|
191
|
+
MODEL_DB.sqls.last.should include("month = 2")
|
192
|
+
MODEL_DB.sqls.last.should include("day = 3")
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
if RUBY_VERSION >= '1.9.0'
|
3
|
+
describe "force_encoding plugin" do
|
4
|
+
before do
|
5
|
+
@c = Class.new(Sequel::Model) do
|
6
|
+
end
|
7
|
+
@c.columns :id, :x
|
8
|
+
@c.plugin :force_encoding, 'UTF-8'
|
9
|
+
@e1 = Encoding.find('UTF-8')
|
10
|
+
end
|
11
|
+
|
12
|
+
specify "should force encoding to given encoding on load" do
|
13
|
+
s = 'blah'
|
14
|
+
s.force_encoding('US-ASCII')
|
15
|
+
o = @c.load(:id=>1, :x=>s)
|
16
|
+
o.x.should == 'blah'
|
17
|
+
o.x.encoding.should == @e1
|
18
|
+
end
|
19
|
+
|
20
|
+
specify "should force encoding to given encoding when setting column values" do
|
21
|
+
s = 'blah'
|
22
|
+
s.force_encoding('US-ASCII')
|
23
|
+
o = @c.new(:x=>s)
|
24
|
+
o.x.should == 'blah'
|
25
|
+
o.x.encoding.should == @e1
|
26
|
+
end
|
27
|
+
|
28
|
+
specify "should have a forced_encoding class accessor" do
|
29
|
+
s = 'blah'
|
30
|
+
s.force_encoding('US-ASCII')
|
31
|
+
@c.forced_encoding = 'Windows-1258'
|
32
|
+
o = @c.load(:id=>1, :x=>s)
|
33
|
+
o.x.should == 'blah'
|
34
|
+
o.x.encoding.should == Encoding.find('Windows-1258')
|
35
|
+
end
|
36
|
+
|
37
|
+
specify "should not force encoding if forced_encoding is nil" do
|
38
|
+
s = 'blah'
|
39
|
+
s.force_encoding('US-ASCII')
|
40
|
+
@c.forced_encoding = nil
|
41
|
+
o = @c.load(:id=>1, :x=>s)
|
42
|
+
o.x.should == 'blah'
|
43
|
+
o.x.encoding.should == Encoding.find('US-ASCII')
|
44
|
+
end
|
45
|
+
|
46
|
+
specify "should work correctly when subclassing" do
|
47
|
+
c = Class.new(@c)
|
48
|
+
s = 'blah'
|
49
|
+
s.force_encoding('US-ASCII')
|
50
|
+
o = c.load(:id=>1, :x=>s)
|
51
|
+
o.x.should == 'blah'
|
52
|
+
o.x.encoding.should == @e1
|
53
|
+
|
54
|
+
c.plugin :force_encoding, 'UTF-16LE'
|
55
|
+
s = ''
|
56
|
+
s.force_encoding('US-ASCII')
|
57
|
+
o = c.load(:id=>1, :x=>s)
|
58
|
+
o.x.should == ''
|
59
|
+
o.x.encoding.should == Encoding.find('UTF-16LE')
|
60
|
+
|
61
|
+
@c.plugin :force_encoding, 'UTF-32LE'
|
62
|
+
s = ''
|
63
|
+
s.force_encoding('US-ASCII')
|
64
|
+
o = @c.load(:id=>1, :x=>s)
|
65
|
+
o.x.should == ''
|
66
|
+
o.x.encoding.should == Encoding.find('UTF-32LE')
|
67
|
+
|
68
|
+
s = ''
|
69
|
+
s.force_encoding('US-ASCII')
|
70
|
+
o = c.load(:id=>1, :x=>s)
|
71
|
+
o.x.should == ''
|
72
|
+
o.x.encoding.should == Encoding.find('UTF-16LE')
|
73
|
+
end
|
74
|
+
|
75
|
+
specify "should work when saving new model instances" do
|
76
|
+
o = @c.new
|
77
|
+
@c.dataset = ds = MODEL_DB[:a]
|
78
|
+
def ds.first
|
79
|
+
s = 'blah'
|
80
|
+
s.force_encoding('US-ASCII')
|
81
|
+
{:id=>1, :x=>s}
|
82
|
+
end
|
83
|
+
o.save
|
84
|
+
o.x.should == 'blah'
|
85
|
+
o.x.encoding.should == @e1
|
86
|
+
end
|
87
|
+
|
88
|
+
specify "should work when refreshing model instances" do
|
89
|
+
o = @c.load(:id=>1, :x=>'as')
|
90
|
+
@c.dataset = ds = MODEL_DB[:a]
|
91
|
+
def ds.first
|
92
|
+
s = 'blah'
|
93
|
+
s.force_encoding('US-ASCII')
|
94
|
+
{:id=>1, :x=>s}
|
95
|
+
end
|
96
|
+
o.refresh
|
97
|
+
o.x.should == 'blah'
|
98
|
+
o.x.encoding.should == @e1
|
99
|
+
end
|
100
|
+
|
101
|
+
specify "should work when used with the identity_map plugin if the identity_map plugin is setup first" do
|
102
|
+
@c = Class.new(Sequel::Model) do
|
103
|
+
end
|
104
|
+
@c.columns :id, :x
|
105
|
+
@c.plugin :identity_map
|
106
|
+
@c.plugin :force_encoding, 'UTF-8'
|
107
|
+
@c.with_identity_map do
|
108
|
+
o = @c.load(:id=>1)
|
109
|
+
s = 'blah'
|
110
|
+
s.force_encoding('US-ASCII')
|
111
|
+
@c.load(:id=>1, :x=>s)
|
112
|
+
o.x.should == 'blah'
|
113
|
+
o.x.encoding.should == @e1
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,470 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe "Model hooks" do
|
4
|
+
before do
|
5
|
+
MODEL_DB.reset
|
6
|
+
end
|
7
|
+
|
8
|
+
specify "should be definable using a block" do
|
9
|
+
$adds = []
|
10
|
+
c = Class.new(Sequel::Model)
|
11
|
+
c.class_eval do
|
12
|
+
before_save {$adds << 'hi'}
|
13
|
+
end
|
14
|
+
|
15
|
+
c.new.before_save
|
16
|
+
$adds.should == ['hi']
|
17
|
+
end
|
18
|
+
|
19
|
+
specify "should be definable using a method name" do
|
20
|
+
$adds = []
|
21
|
+
c = Class.new(Sequel::Model)
|
22
|
+
c.class_eval do
|
23
|
+
def bye; $adds << 'bye'; end
|
24
|
+
before_save :bye
|
25
|
+
end
|
26
|
+
|
27
|
+
c.new.before_save
|
28
|
+
$adds.should == ['bye']
|
29
|
+
end
|
30
|
+
|
31
|
+
specify "should be additive" do
|
32
|
+
$adds = []
|
33
|
+
c = Class.new(Sequel::Model)
|
34
|
+
c.class_eval do
|
35
|
+
after_save {$adds << 'hyiyie'}
|
36
|
+
after_save {$adds << 'byiyie'}
|
37
|
+
end
|
38
|
+
|
39
|
+
c.new.after_save
|
40
|
+
$adds.should == ['hyiyie', 'byiyie']
|
41
|
+
end
|
42
|
+
|
43
|
+
specify "before hooks should run in reverse order" do
|
44
|
+
$adds = []
|
45
|
+
c = Class.new(Sequel::Model)
|
46
|
+
c.class_eval do
|
47
|
+
before_save {$adds << 'hyiyie'}
|
48
|
+
before_save {$adds << 'byiyie'}
|
49
|
+
end
|
50
|
+
|
51
|
+
c.new.before_save
|
52
|
+
$adds.should == ['byiyie', 'hyiyie']
|
53
|
+
end
|
54
|
+
|
55
|
+
specify "should not be additive if the method or tag already exists" do
|
56
|
+
$adds = []
|
57
|
+
c = Class.new(Sequel::Model)
|
58
|
+
c.class_eval do
|
59
|
+
def bye; $adds << 'bye'; end
|
60
|
+
before_save :bye
|
61
|
+
before_save :bye
|
62
|
+
end
|
63
|
+
|
64
|
+
c.new.before_save
|
65
|
+
$adds.should == ['bye']
|
66
|
+
|
67
|
+
$adds = []
|
68
|
+
d = Class.new(Sequel::Model)
|
69
|
+
d.class_eval do
|
70
|
+
before_save(:bye){$adds << 'hyiyie'}
|
71
|
+
before_save(:bye){$adds << 'byiyie'}
|
72
|
+
end
|
73
|
+
|
74
|
+
d.new.before_save
|
75
|
+
$adds.should == ['byiyie']
|
76
|
+
|
77
|
+
$adds = []
|
78
|
+
e = Class.new(Sequel::Model)
|
79
|
+
e.class_eval do
|
80
|
+
def bye; $adds << 'bye'; end
|
81
|
+
before_save :bye
|
82
|
+
before_save(:bye){$adds << 'byiyie'}
|
83
|
+
end
|
84
|
+
|
85
|
+
e.new.before_save
|
86
|
+
$adds.should == ['byiyie']
|
87
|
+
|
88
|
+
$adds = []
|
89
|
+
e = Class.new(Sequel::Model)
|
90
|
+
e.class_eval do
|
91
|
+
def bye; $adds << 'bye'; end
|
92
|
+
before_save(:bye){$adds << 'byiyie'}
|
93
|
+
before_save :bye
|
94
|
+
end
|
95
|
+
|
96
|
+
e.new.before_save
|
97
|
+
$adds.should == ['bye']
|
98
|
+
end
|
99
|
+
|
100
|
+
specify "should be inheritable" do
|
101
|
+
# pending
|
102
|
+
|
103
|
+
$adds = []
|
104
|
+
a = Class.new(Sequel::Model)
|
105
|
+
a.class_eval do
|
106
|
+
after_save {$adds << '123'}
|
107
|
+
end
|
108
|
+
|
109
|
+
b = Class.new(a)
|
110
|
+
b.class_eval do
|
111
|
+
after_save {$adds << '456'}
|
112
|
+
after_save {$adds << '789'}
|
113
|
+
end
|
114
|
+
|
115
|
+
b.new.after_save
|
116
|
+
$adds.should == ['123', '456', '789']
|
117
|
+
end
|
118
|
+
|
119
|
+
specify "should be overridable in descendant classes" do
|
120
|
+
$adds = []
|
121
|
+
a = Class.new(Sequel::Model)
|
122
|
+
a.class_eval do
|
123
|
+
before_save {$adds << '123'}
|
124
|
+
end
|
125
|
+
|
126
|
+
b = Class.new(a)
|
127
|
+
b.class_eval do
|
128
|
+
def before_save; $adds << '456'; end
|
129
|
+
end
|
130
|
+
|
131
|
+
a.new.before_save
|
132
|
+
$adds.should == ['123']
|
133
|
+
$adds = []
|
134
|
+
b.new.before_save
|
135
|
+
$adds.should == ['456']
|
136
|
+
end
|
137
|
+
|
138
|
+
specify "should stop processing if a hook returns false" do
|
139
|
+
$flag = true
|
140
|
+
$adds = []
|
141
|
+
|
142
|
+
a = Class.new(Sequel::Model)
|
143
|
+
a.class_eval do
|
144
|
+
after_save {$adds << 'blah'; $flag}
|
145
|
+
after_save {$adds << 'cruel'}
|
146
|
+
end
|
147
|
+
|
148
|
+
a.new.after_save
|
149
|
+
$adds.should == ['blah', 'cruel']
|
150
|
+
|
151
|
+
# chain should not break on nil
|
152
|
+
$adds = []
|
153
|
+
$flag = nil
|
154
|
+
a.new.after_save
|
155
|
+
$adds.should == ['blah', 'cruel']
|
156
|
+
|
157
|
+
$adds = []
|
158
|
+
$flag = false
|
159
|
+
a.new.after_save
|
160
|
+
$adds.should == ['blah']
|
161
|
+
|
162
|
+
b = Class.new(a)
|
163
|
+
b.class_eval do
|
164
|
+
after_save {$adds << 'mau'}
|
165
|
+
end
|
166
|
+
|
167
|
+
$adds = []
|
168
|
+
b.new.after_save
|
169
|
+
$adds.should == ['blah']
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "Model#after_initialize" do
|
174
|
+
specify "should be called after initialization" do
|
175
|
+
$values1 = nil
|
176
|
+
$reached_after_initialized = false
|
177
|
+
|
178
|
+
a = Class.new(Sequel::Model)
|
179
|
+
a.class_eval do
|
180
|
+
columns :x, :y
|
181
|
+
after_initialize do
|
182
|
+
$values1 = @values.clone
|
183
|
+
$reached_after_initialized = true
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
a.new(:x => 1, :y => 2)
|
188
|
+
$values1.should == {:x => 1, :y => 2}
|
189
|
+
$reached_after_initialized.should == true
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "Model#before_create && Model#after_create" do
|
194
|
+
before do
|
195
|
+
MODEL_DB.reset
|
196
|
+
|
197
|
+
@c = Class.new(Sequel::Model(:items))
|
198
|
+
@c.class_eval do
|
199
|
+
columns :x
|
200
|
+
no_primary_key
|
201
|
+
|
202
|
+
after_create {MODEL_DB << "BLAH after"}
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
specify "should be called around new record creation" do
|
207
|
+
@c.before_create {MODEL_DB << "BLAH before"}
|
208
|
+
@c.create(:x => 2)
|
209
|
+
MODEL_DB.sqls.should == [
|
210
|
+
'BLAH before',
|
211
|
+
'INSERT INTO items (x) VALUES (2)',
|
212
|
+
'BLAH after'
|
213
|
+
]
|
214
|
+
end
|
215
|
+
|
216
|
+
specify ".create should cancel the save and raise an error if before_create returns false and raise_on_save_failure is true" do
|
217
|
+
@c.before_create{false}
|
218
|
+
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
219
|
+
proc{@c.create(:x => 2)}.should raise_error(Sequel::BeforeHookFailed)
|
220
|
+
MODEL_DB.sqls.should == []
|
221
|
+
end
|
222
|
+
|
223
|
+
specify ".create should cancel the save and return nil if before_create returns false and raise_on_save_failure is false" do
|
224
|
+
@c.before_create{false}
|
225
|
+
@c.raise_on_save_failure = false
|
226
|
+
@c.create(:x => 2).should == nil
|
227
|
+
MODEL_DB.sqls.should == []
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "Model#before_update && Model#after_update" do
|
232
|
+
before do
|
233
|
+
MODEL_DB.reset
|
234
|
+
|
235
|
+
@c = Class.new(Sequel::Model(:items))
|
236
|
+
@c.class_eval do
|
237
|
+
after_update {MODEL_DB << "BLAH after"}
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
specify "should be called around record update" do
|
242
|
+
@c.before_update {MODEL_DB << "BLAH before"}
|
243
|
+
m = @c.load(:id => 2233, :x=>123)
|
244
|
+
m.save
|
245
|
+
MODEL_DB.sqls.should == [
|
246
|
+
'BLAH before',
|
247
|
+
'UPDATE items SET x = 123 WHERE (id = 2233)',
|
248
|
+
'BLAH after'
|
249
|
+
]
|
250
|
+
end
|
251
|
+
|
252
|
+
specify "#save should cancel the save and raise an error if before_update returns false and raise_on_save_failure is true" do
|
253
|
+
@c.before_update{false}
|
254
|
+
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
255
|
+
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
256
|
+
MODEL_DB.sqls.should == []
|
257
|
+
end
|
258
|
+
|
259
|
+
specify "#save should cancel the save and return nil if before_update returns false and raise_on_save_failure is false" do
|
260
|
+
@c.before_update{false}
|
261
|
+
@c.raise_on_save_failure = false
|
262
|
+
@c.load(:id => 2233).save.should == nil
|
263
|
+
MODEL_DB.sqls.should == []
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe "Model#before_save && Model#after_save" do
|
268
|
+
before do
|
269
|
+
MODEL_DB.reset
|
270
|
+
|
271
|
+
@c = Class.new(Sequel::Model(:items))
|
272
|
+
@c.class_eval do
|
273
|
+
columns :x
|
274
|
+
after_save {MODEL_DB << "BLAH after"}
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
specify "should be called around record update" do
|
279
|
+
@c.before_save {MODEL_DB << "BLAH before"}
|
280
|
+
m = @c.load(:id => 2233, :x=>123)
|
281
|
+
m.save
|
282
|
+
MODEL_DB.sqls.should == [
|
283
|
+
'BLAH before',
|
284
|
+
'UPDATE items SET x = 123 WHERE (id = 2233)',
|
285
|
+
'BLAH after'
|
286
|
+
]
|
287
|
+
end
|
288
|
+
|
289
|
+
specify "should be called around record creation" do
|
290
|
+
@c.before_save {MODEL_DB << "BLAH before"}
|
291
|
+
@c.no_primary_key
|
292
|
+
@c.create(:x => 2)
|
293
|
+
MODEL_DB.sqls.should == [
|
294
|
+
'BLAH before',
|
295
|
+
'INSERT INTO items (x) VALUES (2)',
|
296
|
+
'BLAH after'
|
297
|
+
]
|
298
|
+
end
|
299
|
+
|
300
|
+
specify "#save should cancel the save and raise an error if before_save returns false and raise_on_save_failure is true" do
|
301
|
+
@c.before_save{false}
|
302
|
+
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
303
|
+
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
304
|
+
MODEL_DB.sqls.should == []
|
305
|
+
end
|
306
|
+
|
307
|
+
specify "#save should cancel the save and return nil if before_save returns false and raise_on_save_failure is false" do
|
308
|
+
@c.before_save{false}
|
309
|
+
@c.raise_on_save_failure = false
|
310
|
+
@c.load(:id => 2233).save.should == nil
|
311
|
+
MODEL_DB.sqls.should == []
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
describe "Model#before_destroy && Model#after_destroy" do
|
316
|
+
before do
|
317
|
+
MODEL_DB.reset
|
318
|
+
|
319
|
+
@c = Class.new(Sequel::Model(:items))
|
320
|
+
@c.class_eval do
|
321
|
+
after_destroy {MODEL_DB << "BLAH after"}
|
322
|
+
|
323
|
+
def delete
|
324
|
+
MODEL_DB << "DELETE BLAH"
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
specify "should be called around record destruction" do
|
330
|
+
@c.before_destroy {MODEL_DB << "BLAH before"}
|
331
|
+
m = @c.load(:id => 2233)
|
332
|
+
m.destroy
|
333
|
+
MODEL_DB.sqls.should == [
|
334
|
+
'BLAH before',
|
335
|
+
'DELETE BLAH',
|
336
|
+
'BLAH after'
|
337
|
+
]
|
338
|
+
end
|
339
|
+
|
340
|
+
specify "#destroy should cancel the destroy and raise an error if before_destroy returns false and raise_on_save_failure is true" do
|
341
|
+
@c.before_destroy{false}
|
342
|
+
proc{@c.load(:id => 2233).destroy}.should raise_error(Sequel::BeforeHookFailed)
|
343
|
+
MODEL_DB.sqls.should == []
|
344
|
+
end
|
345
|
+
|
346
|
+
specify "#destroy should cancel the destroy and return nil if before_destroy returns false and raise_on_save_failure is false" do
|
347
|
+
@c.before_destroy{false}
|
348
|
+
@c.raise_on_save_failure = false
|
349
|
+
@c.load(:id => 2233).destroy.should == nil
|
350
|
+
MODEL_DB.sqls.should == []
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
describe "Model#before_validation && Model#after_validation" do
|
355
|
+
before do
|
356
|
+
MODEL_DB.reset
|
357
|
+
|
358
|
+
@c = Class.new(Sequel::Model(:items))
|
359
|
+
@c.class_eval do
|
360
|
+
after_validation{MODEL_DB << "BLAH after"}
|
361
|
+
|
362
|
+
def self.validate(o)
|
363
|
+
o.errors[:id] << 'not valid' unless o[:id] == 2233
|
364
|
+
end
|
365
|
+
columns :id
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
specify "should be called around validation" do
|
370
|
+
@c.before_validation{MODEL_DB << "BLAH before"}
|
371
|
+
m = @c.load(:id => 2233)
|
372
|
+
m.should be_valid
|
373
|
+
MODEL_DB.sqls.should == ['BLAH before', 'BLAH after']
|
374
|
+
|
375
|
+
MODEL_DB.sqls.clear
|
376
|
+
m = @c.load(:id => 22)
|
377
|
+
m.should_not be_valid
|
378
|
+
MODEL_DB.sqls.should == ['BLAH before', 'BLAH after']
|
379
|
+
end
|
380
|
+
|
381
|
+
specify "should be called when calling save" do
|
382
|
+
@c.before_validation{MODEL_DB << "BLAH before"}
|
383
|
+
m = @c.load(:id => 2233, :x=>123)
|
384
|
+
m.save.should == m
|
385
|
+
MODEL_DB.sqls.should == ['BLAH before', 'BLAH after', 'UPDATE items SET x = 123 WHERE (id = 2233)']
|
386
|
+
|
387
|
+
MODEL_DB.sqls.clear
|
388
|
+
m = @c.load(:id => 22)
|
389
|
+
m.raise_on_save_failure = false
|
390
|
+
m.save.should == nil
|
391
|
+
MODEL_DB.sqls.should == ['BLAH before', 'BLAH after']
|
392
|
+
end
|
393
|
+
|
394
|
+
specify "#save should cancel the save and raise an error if before_validation returns false and raise_on_save_failure is true" do
|
395
|
+
@c.before_validation{false}
|
396
|
+
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
397
|
+
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
398
|
+
MODEL_DB.sqls.should == []
|
399
|
+
end
|
400
|
+
|
401
|
+
specify "#save should cancel the save and return nil if before_validation returns false and raise_on_save_failure is false" do
|
402
|
+
@c.before_validation{false}
|
403
|
+
@c.raise_on_save_failure = false
|
404
|
+
@c.load(:id => 2233).save.should == nil
|
405
|
+
MODEL_DB.sqls.should == []
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
describe "Model.has_hooks?" do
|
410
|
+
before do
|
411
|
+
@c = Class.new(Sequel::Model(:items))
|
412
|
+
end
|
413
|
+
|
414
|
+
specify "should return false if no hooks are defined" do
|
415
|
+
@c.has_hooks?(:before_save).should be_false
|
416
|
+
end
|
417
|
+
|
418
|
+
specify "should return true if hooks are defined" do
|
419
|
+
@c.before_save {'blah'}
|
420
|
+
@c.has_hooks?(:before_save).should be_true
|
421
|
+
end
|
422
|
+
|
423
|
+
specify "should return true if hooks are inherited" do
|
424
|
+
@d = Class.new(@c)
|
425
|
+
@d.has_hooks?(:before_save).should be_false
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
describe "Model#add_hook_type" do
|
430
|
+
before do
|
431
|
+
class Foo < Sequel::Model(:items)
|
432
|
+
add_hook_type :before_bar, :after_bar
|
433
|
+
|
434
|
+
def bar
|
435
|
+
return :b if before_bar == false
|
436
|
+
return :a if after_bar == false
|
437
|
+
true
|
438
|
+
end
|
439
|
+
end
|
440
|
+
@f = Class.new(Foo)
|
441
|
+
end
|
442
|
+
|
443
|
+
specify "should have before_bar and after_bar class methods" do
|
444
|
+
@f.should respond_to(:before_bar)
|
445
|
+
@f.should respond_to(:before_bar)
|
446
|
+
end
|
447
|
+
|
448
|
+
specify "should have before_bar and after_bar instance methods" do
|
449
|
+
@f.new.should respond_to(:before_bar)
|
450
|
+
@f.new.should respond_to(:before_bar)
|
451
|
+
end
|
452
|
+
|
453
|
+
specify "it should return true for bar when before_bar and after_bar hooks are returing true" do
|
454
|
+
a = 1
|
455
|
+
@f.before_bar { a += 1}
|
456
|
+
@f.new.bar.should be_true
|
457
|
+
a.should == 2
|
458
|
+
@f.after_bar { a *= 2}
|
459
|
+
@f.new.bar.should be_true
|
460
|
+
a.should == 6
|
461
|
+
end
|
462
|
+
|
463
|
+
specify "it should return nil for bar when before_bar and after_bar hooks are returing false" do
|
464
|
+
@f.new.bar.should be_true
|
465
|
+
@f.after_bar { false }
|
466
|
+
@f.new.bar.should == :a
|
467
|
+
@f.before_bar { false }
|
468
|
+
@f.new.bar.should == :b
|
469
|
+
end
|
470
|
+
end
|