sequel 3.47.0 → 3.48.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +230 -0
  3. data/README.rdoc +31 -40
  4. data/Rakefile +1 -14
  5. data/doc/active_record.rdoc +29 -29
  6. data/doc/association_basics.rdoc +4 -13
  7. data/doc/cheat_sheet.rdoc +8 -6
  8. data/doc/code_order.rdoc +89 -0
  9. data/doc/core_extensions.rdoc +3 -3
  10. data/doc/dataset_basics.rdoc +7 -8
  11. data/doc/dataset_filtering.rdoc +7 -2
  12. data/doc/mass_assignment.rdoc +2 -3
  13. data/doc/migration.rdoc +8 -8
  14. data/doc/model_hooks.rdoc +11 -7
  15. data/doc/object_model.rdoc +2 -2
  16. data/doc/opening_databases.rdoc +5 -14
  17. data/doc/prepared_statements.rdoc +5 -9
  18. data/doc/querying.rdoc +23 -28
  19. data/doc/reflection.rdoc +11 -0
  20. data/doc/release_notes/3.48.0.txt +477 -0
  21. data/doc/schema_modification.rdoc +12 -5
  22. data/doc/security.rdoc +2 -2
  23. data/doc/sharding.rdoc +1 -2
  24. data/doc/sql.rdoc +10 -13
  25. data/doc/testing.rdoc +8 -4
  26. data/doc/transactions.rdoc +2 -2
  27. data/doc/validations.rdoc +40 -17
  28. data/doc/virtual_rows.rdoc +2 -2
  29. data/lib/sequel/adapters/ado.rb +25 -20
  30. data/lib/sequel/adapters/ado/access.rb +1 -0
  31. data/lib/sequel/adapters/ado/mssql.rb +1 -0
  32. data/lib/sequel/adapters/db2.rb +9 -7
  33. data/lib/sequel/adapters/dbi.rb +16 -16
  34. data/lib/sequel/adapters/do.rb +17 -18
  35. data/lib/sequel/adapters/do/mysql.rb +1 -0
  36. data/lib/sequel/adapters/do/postgres.rb +2 -0
  37. data/lib/sequel/adapters/do/sqlite.rb +1 -0
  38. data/lib/sequel/adapters/firebird.rb +5 -7
  39. data/lib/sequel/adapters/ibmdb.rb +23 -20
  40. data/lib/sequel/adapters/informix.rb +8 -2
  41. data/lib/sequel/adapters/jdbc.rb +39 -35
  42. data/lib/sequel/adapters/jdbc/as400.rb +1 -0
  43. data/lib/sequel/adapters/jdbc/cubrid.rb +1 -0
  44. data/lib/sequel/adapters/jdbc/db2.rb +1 -0
  45. data/lib/sequel/adapters/jdbc/derby.rb +1 -0
  46. data/lib/sequel/adapters/jdbc/firebird.rb +1 -0
  47. data/lib/sequel/adapters/jdbc/h2.rb +1 -0
  48. data/lib/sequel/adapters/jdbc/hsqldb.rb +1 -0
  49. data/lib/sequel/adapters/jdbc/informix.rb +1 -0
  50. data/lib/sequel/adapters/jdbc/jtds.rb +1 -0
  51. data/lib/sequel/adapters/jdbc/mssql.rb +1 -0
  52. data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
  53. data/lib/sequel/adapters/jdbc/oracle.rb +1 -0
  54. data/lib/sequel/adapters/jdbc/postgresql.rb +2 -0
  55. data/lib/sequel/adapters/jdbc/progress.rb +1 -0
  56. data/lib/sequel/adapters/jdbc/sqlite.rb +1 -0
  57. data/lib/sequel/adapters/jdbc/sqlserver.rb +1 -0
  58. data/lib/sequel/adapters/mock.rb +30 -31
  59. data/lib/sequel/adapters/mysql.rb +6 -7
  60. data/lib/sequel/adapters/mysql2.rb +5 -6
  61. data/lib/sequel/adapters/odbc.rb +22 -20
  62. data/lib/sequel/adapters/odbc/mssql.rb +1 -0
  63. data/lib/sequel/adapters/openbase.rb +4 -1
  64. data/lib/sequel/adapters/oracle.rb +10 -8
  65. data/lib/sequel/adapters/postgres.rb +12 -10
  66. data/lib/sequel/adapters/shared/access.rb +6 -0
  67. data/lib/sequel/adapters/shared/cubrid.rb +2 -0
  68. data/lib/sequel/adapters/shared/db2.rb +2 -0
  69. data/lib/sequel/adapters/shared/firebird.rb +2 -0
  70. data/lib/sequel/adapters/shared/informix.rb +2 -0
  71. data/lib/sequel/adapters/shared/mssql.rb +14 -8
  72. data/lib/sequel/adapters/shared/mysql.rb +6 -0
  73. data/lib/sequel/adapters/shared/oracle.rb +2 -0
  74. data/lib/sequel/adapters/shared/postgres.rb +14 -4
  75. data/lib/sequel/adapters/shared/progress.rb +1 -0
  76. data/lib/sequel/adapters/shared/sqlite.rb +4 -3
  77. data/lib/sequel/adapters/sqlite.rb +6 -7
  78. data/lib/sequel/adapters/swift.rb +20 -21
  79. data/lib/sequel/adapters/swift/mysql.rb +1 -0
  80. data/lib/sequel/adapters/swift/postgres.rb +2 -0
  81. data/lib/sequel/adapters/swift/sqlite.rb +1 -0
  82. data/lib/sequel/adapters/tinytds.rb +5 -6
  83. data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +68 -0
  84. data/lib/sequel/connection_pool.rb +1 -1
  85. data/lib/sequel/core.rb +57 -50
  86. data/lib/sequel/database/connecting.rb +9 -10
  87. data/lib/sequel/database/dataset.rb +11 -6
  88. data/lib/sequel/database/dataset_defaults.rb +61 -69
  89. data/lib/sequel/database/features.rb +21 -0
  90. data/lib/sequel/database/misc.rb +23 -3
  91. data/lib/sequel/database/query.rb +13 -7
  92. data/lib/sequel/database/schema_methods.rb +6 -6
  93. data/lib/sequel/database/transactions.rb +1 -0
  94. data/lib/sequel/dataset/actions.rb +51 -38
  95. data/lib/sequel/dataset/features.rb +1 -0
  96. data/lib/sequel/dataset/graph.rb +9 -33
  97. data/lib/sequel/dataset/misc.rb +30 -5
  98. data/lib/sequel/dataset/mutation.rb +2 -3
  99. data/lib/sequel/dataset/prepared_statements.rb +1 -1
  100. data/lib/sequel/dataset/query.rb +91 -27
  101. data/lib/sequel/dataset/sql.rb +40 -6
  102. data/lib/sequel/deprecated.rb +74 -0
  103. data/lib/sequel/deprecated_core_extensions.rb +135 -0
  104. data/lib/sequel/extensions/columns_introspection.rb +1 -5
  105. data/lib/sequel/extensions/core_extensions.rb +10 -3
  106. data/lib/sequel/extensions/date_arithmetic.rb +1 -0
  107. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +33 -0
  108. data/lib/sequel/extensions/filter_having.rb +58 -0
  109. data/lib/sequel/extensions/graph_each.rb +63 -0
  110. data/lib/sequel/extensions/hash_aliases.rb +44 -0
  111. data/lib/sequel/extensions/looser_typecasting.rb +14 -3
  112. data/lib/sequel/extensions/migration.rb +2 -3
  113. data/lib/sequel/extensions/named_timezones.rb +14 -1
  114. data/lib/sequel/extensions/null_dataset.rb +7 -1
  115. data/lib/sequel/extensions/pagination.rb +15 -5
  116. data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -0
  117. data/lib/sequel/extensions/pg_hstore_ops.rb +48 -14
  118. data/lib/sequel/extensions/pg_json.rb +7 -7
  119. data/lib/sequel/extensions/pg_range_ops.rb +8 -2
  120. data/lib/sequel/extensions/pg_statement_cache.rb +1 -0
  121. data/lib/sequel/extensions/pretty_table.rb +13 -4
  122. data/lib/sequel/extensions/query.rb +21 -4
  123. data/lib/sequel/extensions/ruby18_symbol_extensions.rb +22 -0
  124. data/lib/sequel/extensions/schema_caching.rb +10 -7
  125. data/lib/sequel/extensions/schema_dumper.rb +35 -48
  126. data/lib/sequel/extensions/select_remove.rb +13 -4
  127. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +117 -0
  128. data/lib/sequel/extensions/set_overrides.rb +43 -0
  129. data/lib/sequel/extensions/to_dot.rb +6 -0
  130. data/lib/sequel/model.rb +12 -6
  131. data/lib/sequel/model/associations.rb +80 -38
  132. data/lib/sequel/model/base.rb +137 -52
  133. data/lib/sequel/model/errors.rb +7 -2
  134. data/lib/sequel/plugins/active_model.rb +13 -0
  135. data/lib/sequel/plugins/after_initialize.rb +43 -0
  136. data/lib/sequel/plugins/association_proxies.rb +63 -7
  137. data/lib/sequel/plugins/auto_validations.rb +56 -16
  138. data/lib/sequel/plugins/blacklist_security.rb +63 -0
  139. data/lib/sequel/plugins/class_table_inheritance.rb +9 -0
  140. data/lib/sequel/plugins/constraint_validations.rb +50 -8
  141. data/lib/sequel/plugins/dataset_associations.rb +2 -0
  142. data/lib/sequel/plugins/hook_class_methods.rb +7 -1
  143. data/lib/sequel/plugins/identity_map.rb +4 -0
  144. data/lib/sequel/plugins/json_serializer.rb +32 -13
  145. data/lib/sequel/plugins/optimistic_locking.rb +1 -1
  146. data/lib/sequel/plugins/rcte_tree.rb +4 -4
  147. data/lib/sequel/plugins/scissors.rb +33 -0
  148. data/lib/sequel/plugins/serialization.rb +1 -1
  149. data/lib/sequel/plugins/single_table_inheritance.rb +6 -0
  150. data/lib/sequel/plugins/tree.rb +5 -1
  151. data/lib/sequel/plugins/validation_class_methods.rb +2 -1
  152. data/lib/sequel/plugins/validation_helpers.rb +15 -11
  153. data/lib/sequel/plugins/xml_serializer.rb +12 -3
  154. data/lib/sequel/sql.rb +12 -2
  155. data/lib/sequel/timezones.rb +1 -1
  156. data/lib/sequel/version.rb +1 -1
  157. data/lib/sequel_core.rb +1 -0
  158. data/lib/sequel_model.rb +1 -0
  159. data/spec/adapters/mssql_spec.rb +24 -57
  160. data/spec/adapters/postgres_spec.rb +27 -55
  161. data/spec/adapters/spec_helper.rb +1 -1
  162. data/spec/adapters/sqlite_spec.rb +1 -1
  163. data/spec/bin_spec.rb +251 -0
  164. data/spec/core/database_spec.rb +46 -32
  165. data/spec/core/dataset_spec.rb +233 -181
  166. data/spec/core/deprecated_spec.rb +78 -0
  167. data/spec/core/expression_filters_spec.rb +3 -4
  168. data/spec/core/mock_adapter_spec.rb +9 -9
  169. data/spec/core/object_graph_spec.rb +9 -19
  170. data/spec/core/schema_spec.rb +3 -1
  171. data/spec/core/spec_helper.rb +19 -0
  172. data/spec/core_extensions_spec.rb +80 -30
  173. data/spec/extensions/after_initialize_spec.rb +24 -0
  174. data/spec/extensions/association_proxies_spec.rb +37 -1
  175. data/spec/extensions/auto_validations_spec.rb +20 -4
  176. data/spec/extensions/blacklist_security_spec.rb +87 -0
  177. data/spec/extensions/boolean_readers_spec.rb +2 -1
  178. data/spec/extensions/class_table_inheritance_spec.rb +7 -0
  179. data/spec/extensions/columns_introspection_spec.rb +3 -3
  180. data/spec/extensions/constraint_validations_plugin_spec.rb +83 -5
  181. data/spec/extensions/core_refinements_spec.rb +7 -7
  182. data/spec/extensions/dataset_associations_spec.rb +2 -2
  183. data/spec/extensions/date_arithmetic_spec.rb +1 -1
  184. data/spec/extensions/defaults_setter_spec.rb +2 -1
  185. data/spec/extensions/empty_array_ignore_nulls_spec.rb +24 -0
  186. data/spec/extensions/filter_having_spec.rb +40 -0
  187. data/spec/extensions/graph_each_spec.rb +109 -0
  188. data/spec/extensions/hash_aliases_spec.rb +16 -0
  189. data/spec/extensions/hook_class_methods_spec.rb +2 -2
  190. data/spec/extensions/identity_map_spec.rb +3 -3
  191. data/spec/extensions/json_serializer_spec.rb +19 -19
  192. data/spec/extensions/lazy_attributes_spec.rb +1 -0
  193. data/spec/extensions/list_spec.rb +13 -13
  194. data/spec/extensions/looser_typecasting_spec.rb +10 -3
  195. data/spec/extensions/many_through_many_spec.rb +1 -1
  196. data/spec/extensions/migration_spec.rb +7 -7
  197. data/spec/extensions/named_timezones_spec.rb +6 -0
  198. data/spec/extensions/nested_attributes_spec.rb +2 -2
  199. data/spec/extensions/null_dataset_spec.rb +1 -1
  200. data/spec/extensions/pagination_spec.rb +2 -2
  201. data/spec/extensions/pg_hstore_ops_spec.rb +75 -0
  202. data/spec/extensions/pg_range_ops_spec.rb +4 -2
  203. data/spec/extensions/pg_row_plugin_spec.rb +1 -1
  204. data/spec/extensions/pretty_table_spec.rb +1 -1
  205. data/spec/extensions/query_literals_spec.rb +1 -1
  206. data/spec/extensions/query_spec.rb +3 -3
  207. data/spec/extensions/schema_caching_spec.rb +3 -3
  208. data/spec/extensions/schema_dumper_spec.rb +27 -2
  209. data/spec/extensions/schema_spec.rb +2 -2
  210. data/spec/extensions/scissors_spec.rb +26 -0
  211. data/spec/extensions/select_remove_spec.rb +1 -1
  212. data/spec/extensions/sequel_3_dataset_methods_spec.rb +102 -0
  213. data/spec/extensions/set_overrides_spec.rb +45 -0
  214. data/spec/extensions/single_table_inheritance_spec.rb +10 -0
  215. data/spec/extensions/spec_helper.rb +24 -1
  216. data/spec/extensions/static_cache_spec.rb +1 -1
  217. data/spec/extensions/string_stripper_spec.rb +2 -1
  218. data/spec/extensions/to_dot_spec.rb +1 -1
  219. data/spec/extensions/typecast_on_load_spec.rb +3 -2
  220. data/spec/extensions/update_primary_key_spec.rb +2 -2
  221. data/spec/extensions/validation_class_methods_spec.rb +19 -19
  222. data/spec/extensions/validation_helpers_spec.rb +30 -21
  223. data/spec/extensions/xml_serializer_spec.rb +5 -5
  224. data/spec/integration/associations_test.rb +10 -30
  225. data/spec/integration/dataset_test.rb +20 -24
  226. data/spec/integration/eager_loader_test.rb +5 -5
  227. data/spec/integration/model_test.rb +3 -3
  228. data/spec/integration/plugin_test.rb +7 -39
  229. data/spec/integration/schema_test.rb +4 -38
  230. data/spec/integration/spec_helper.rb +2 -1
  231. data/spec/model/association_reflection_spec.rb +70 -5
  232. data/spec/model/associations_spec.rb +11 -11
  233. data/spec/model/base_spec.rb +25 -8
  234. data/spec/model/class_dataset_methods_spec.rb +143 -0
  235. data/spec/model/dataset_methods_spec.rb +1 -1
  236. data/spec/model/eager_loading_spec.rb +25 -25
  237. data/spec/model/hooks_spec.rb +1 -1
  238. data/spec/model/model_spec.rb +22 -7
  239. data/spec/model/plugins_spec.rb +1 -6
  240. data/spec/model/record_spec.rb +37 -29
  241. data/spec/model/spec_helper.rb +23 -1
  242. data/spec/model/validations_spec.rb +15 -17
  243. metadata +32 -3
@@ -45,9 +45,9 @@ describe "List plugin" do
45
45
 
46
46
  it "should modify the order when using the plugin" do
47
47
  c = Class.new(Sequel::Model(:items))
48
- c.model.dataset.sql.should == 'SELECT * FROM items'
48
+ c.dataset.sql.should == 'SELECT * FROM items'
49
49
  c.plugin :list
50
- c.model.dataset.sql.should == 'SELECT * FROM items ORDER BY position'
50
+ c.dataset.sql.should == 'SELECT * FROM items ORDER BY position'
51
51
  end
52
52
 
53
53
  it "should be able to access the position field as a class attribute" do
@@ -80,10 +80,10 @@ describe "List plugin" do
80
80
  @c.instance_dataset.autoid = @c.dataset.autoid = 1
81
81
  @c.create.values.should == {:id=>1, :position=>1}
82
82
  @c.create.values.should == {:id=>2, :position=>2}
83
- @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
83
+ @db.sqls.should == ["SELECT max(position) AS max FROM items LIMIT 1",
84
84
  "INSERT INTO items (position) VALUES (1)",
85
85
  "SELECT * FROM items WHERE (id = 1) ORDER BY position LIMIT 1",
86
- "SELECT max(position) FROM items LIMIT 1",
86
+ "SELECT max(position) AS max FROM items LIMIT 1",
87
87
  "INSERT INTO items (position) VALUES (2)",
88
88
  "SELECT * FROM items WHERE (id = 2) ORDER BY position LIMIT 1"]
89
89
  end
@@ -98,11 +98,11 @@ describe "List plugin" do
98
98
  sqls.slice!(7).should =~ /INSERT INTO items \((scope_id|position), (scope_id|position)\) VALUES \([12], [12]\)/
99
99
  sqls.slice!(4).should =~ /INSERT INTO items \((scope_id|position), (scope_id|position)\) VALUES \([12], [12]\)/
100
100
  sqls.slice!(1).should =~ /INSERT INTO items \((scope_id|position), (scope_id|position)\) VALUES \(1, 1\)/
101
- sqls.should == ["SELECT max(position) FROM items WHERE (scope_id = 1) LIMIT 1",
101
+ sqls.should == ["SELECT max(position) AS max FROM items WHERE (scope_id = 1) LIMIT 1",
102
102
  "SELECT * FROM items WHERE (id = 1) ORDER BY scope_id, position LIMIT 1",
103
- "SELECT max(position) FROM items WHERE (scope_id = 1) LIMIT 1",
103
+ "SELECT max(position) AS max FROM items WHERE (scope_id = 1) LIMIT 1",
104
104
  "SELECT * FROM items WHERE (id = 2) ORDER BY scope_id, position LIMIT 1",
105
- "SELECT max(position) FROM items WHERE (scope_id = 2) LIMIT 1",
105
+ "SELECT max(position) AS max FROM items WHERE (scope_id = 2) LIMIT 1",
106
106
  "SELECT * FROM items WHERE (id = 3) ORDER BY scope_id, position LIMIT 1"]
107
107
  end
108
108
 
@@ -111,8 +111,8 @@ describe "List plugin" do
111
111
  @o.last_position.should == 10
112
112
  @sc.dataset._fetch = {:max=>20}
113
113
  @so.last_position.should == 20
114
- @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
115
- "SELECT max(position) FROM items WHERE (scope_id = 5) LIMIT 1"]
114
+ @db.sqls.should == ["SELECT max(position) AS max FROM items LIMIT 1",
115
+ "SELECT max(position) AS max FROM items WHERE (scope_id = 5) LIMIT 1"]
116
116
  end
117
117
 
118
118
  it "should have list_dataset return the model's dataset for non scoped lists" do
@@ -127,7 +127,7 @@ describe "List plugin" do
127
127
  @c.dataset._fetch = {:max=>10}
128
128
  @o.move_down.should == @o
129
129
  @o.position.should == 4
130
- @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
130
+ @db.sqls.should == ["SELECT max(position) AS max FROM items LIMIT 1",
131
131
  "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 4))",
132
132
  "UPDATE items SET position = 4 WHERE (id = 7)"]
133
133
  end
@@ -136,7 +136,7 @@ describe "List plugin" do
136
136
  @c.dataset._fetch = {:max=>10}
137
137
  @o.move_down(3).should == @o
138
138
  @o.position.should == 6
139
- @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
139
+ @db.sqls.should == ["SELECT max(position) AS max FROM items LIMIT 1",
140
140
  "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 6))",
141
141
  "UPDATE items SET position = 6 WHERE (id = 7)"]
142
142
  end
@@ -184,7 +184,7 @@ describe "List plugin" do
184
184
  it "should have move_to_bottom move the item to the last position" do
185
185
  @c.dataset._fetch = {:max=>10}
186
186
  @o.move_to_bottom
187
- @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
187
+ @db.sqls.should == ["SELECT max(position) AS max FROM items LIMIT 1",
188
188
  "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 10))",
189
189
  "UPDATE items SET position = 10 WHERE (id = 7)"]
190
190
  end
@@ -213,7 +213,7 @@ describe "List plugin" do
213
213
  @c.dataset._fetch = {:max=>10}
214
214
  @o.move_up(-1).should == @o
215
215
  @o.position.should == 4
216
- @db.sqls.should == ["SELECT max(position) FROM items LIMIT 1",
216
+ @db.sqls.should == ["SELECT max(position) AS max FROM items LIMIT 1",
217
217
  "UPDATE items SET position = (position - 1) WHERE ((position >= 4) AND (position <= 4))",
218
218
  "UPDATE items SET position = 4 WHERE (id = 7)"]
219
219
  end
@@ -2,14 +2,15 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "LooserTypecasting Extension" do
4
4
  before do
5
- @db = Sequel::Database.new({})
5
+ @db = Sequel::Database.new
6
+ def @db.supports_schema_parsing?() true end
6
7
  def @db.schema(*args)
7
- [[:id, {}], [:z, {:type=>:float}], [:b, {:type=>:integer}], [:d, {:type=>:decimal}]]
8
+ [[:id, {}], [:z, {:type=>:float}], [:b, {:type=>:integer}], [:d, {:type=>:decimal}], [:s, {:type=>:string}]]
8
9
  end
9
10
  @c = Class.new(Sequel::Model(@db[:items]))
10
11
  @db.extension(:looser_typecasting)
11
12
  @c.instance_eval do
12
- @columns = [:id, :b, :z, :d]
13
+ @columns = [:id, :b, :z, :d, :s]
13
14
  def columns; @columns; end
14
15
  end
15
16
  end
@@ -24,6 +25,12 @@ describe "LooserTypecasting Extension" do
24
25
  @c.new(:z=>'a').z.should be_a_kind_of(Float)
25
26
  end
26
27
 
28
+ specify "should not raise errors for hash or array input to string columns" do
29
+ @c.new(:s=>'a').s.should == 'a'
30
+ @c.new(:s=>[]).s.should be_a_kind_of(String)
31
+ @c.new(:s=>{}).s.should be_a_kind_of(String)
32
+ end
33
+
27
34
  specify "should not raise errors for invalid strings in decimal columns" do
28
35
  @c.new(:d=>'a').d.should == 0.0
29
36
  @c.new(:d=>'a').d.should be_a_kind_of(BigDecimal)
@@ -652,7 +652,7 @@ describe "Sequel::Plugins::ManyThroughMany eager loading methods" do
652
652
  MODEL_DB.sqls.length.should == 0
653
653
  end
654
654
 
655
- it "should respect the :limit option on a many_through_many association using a :correlated_subquery strategy" do
655
+ qspecify "should respect the :limit option on a many_through_many association using a :correlated_subquery strategy" do
656
656
  @c1.many_through_many :first_two_tags, [[:albums_artists, :artist_id, :album_id], [:albums, :id, :id], [:albums_tags, :album_id, :tag_id]], :class=>Tag, :limit=>2, :eager_limit_strategy=>:correlated_subquery, :order=>:name
657
657
  Tag.dataset._fetch = [{:x_foreign_key_x=>1, :id=>5},{:x_foreign_key_x=>1, :id=>6}]
658
658
  a = @c1.eager(:first_two_tags).all
@@ -231,7 +231,7 @@ describe "Sequel::IntegerMigrator" do
231
231
  @tables_created << name.to_sym
232
232
  end
233
233
 
234
- def dataset(opts={})
234
+ def dataset
235
235
  ds = super
236
236
  ds.extend(Module.new do
237
237
  def count; 1; end
@@ -661,32 +661,32 @@ describe "Sequel::TimestampMigrator" do
661
661
 
662
662
  specify "should use TimestampMigrator if TimestampMigrator.apply is called even for integer migrations directory" do
663
663
  Sequel::TimestampMigrator.apply(@db, "spec/files/integer_migrations")
664
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm1111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_sessions.rb')", "CREATE TABLE sm2222 (smc2 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_nodes.rb')", "CREATE TABLE sm3333 (smc3 integer)", "INSERT INTO schema_migrations (filename) VALUES ('003_3_create_users.rb')"]
664
+ @db.sqls.should == ["SELECT NULL AS nil FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL AS nil FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm1111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_sessions.rb')", "CREATE TABLE sm2222 (smc2 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_nodes.rb')", "CREATE TABLE sm3333 (smc3 integer)", "INSERT INTO schema_migrations (filename) VALUES ('003_3_create_users.rb')"]
665
665
  end
666
666
 
667
667
  specify "should not use transactions by default" do
668
668
  Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_unspecified_migrations")
669
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
669
+ @db.sqls.should == ["SELECT NULL AS nil FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL AS nil FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
670
670
  end
671
671
 
672
672
  specify "should use transactions by default if database supports transactional ddl" do
673
673
  @db.meta_def(:supports_transactional_ddl?){true}
674
674
  Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_unspecified_migrations")
675
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
675
+ @db.sqls.should == ["SELECT NULL AS nil FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL AS nil FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
676
676
  end
677
677
 
678
678
  specify "should support transaction use on a per migration basis" do
679
679
  Sequel::TimestampMigrator.apply(@db, "spec/files/transaction_specified_migrations")
680
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
680
+ @db.sqls.should == ["SELECT NULL AS nil FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL AS nil FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
681
681
  end
682
682
 
683
683
  specify "should force transactions if enabled by the migrator" do
684
684
  Sequel::TimestampMigrator.run(@db, "spec/files/transaction_specified_migrations", :use_transactions=>true)
685
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
685
+ @db.sqls.should == ["SELECT NULL AS nil FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL AS nil FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "BEGIN", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "COMMIT", "BEGIN", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')", "COMMIT"]
686
686
  end
687
687
 
688
688
  specify "should not use transactions if disabled in the migrator" do
689
689
  Sequel::TimestampMigrator.run(@db, "spec/files/transaction_unspecified_migrations", :use_transactions=>false)
690
- @db.sqls.should == ["SELECT NULL FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
690
+ @db.sqls.should == ["SELECT NULL AS nil FROM schema_migrations LIMIT 1", "CREATE TABLE schema_migrations (filename varchar(255) PRIMARY KEY)", "SELECT NULL AS nil FROM schema_info LIMIT 1", "SELECT filename FROM schema_migrations ORDER BY filename", "CREATE TABLE sm11111 (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('001_create_alt_basic.rb')", "CREATE TABLE sm (smc1 integer)", "INSERT INTO schema_migrations (filename) VALUES ('002_create_basic.rb')"]
691
691
  end
692
692
  end
@@ -29,6 +29,12 @@ describe "Sequel named_timezones extension" do
29
29
  Sequel.database_timezone.should == @tz_out
30
30
  end
31
31
 
32
+ it "should convert string arguments for Database#timezone= to TZInfo::Timezone instances for database-specific timezones" do
33
+ @db.extension :named_timezones
34
+ @db.timezone = 'America/Los_Angeles'
35
+ @db.timezone.should == @tz_in
36
+ end
37
+
32
38
  it "should accept TZInfo::Timezone instances in *_timezone=" do
33
39
  Sequel.application_timezone = @tz_in
34
40
  Sequel.database_timezone = @tz_out
@@ -36,7 +36,7 @@ describe "NestedAttributes plugin" do
36
36
  @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
37
37
  @Artist.one_to_many :concerts, :class=>@Concert, :key=>:artist_id
38
38
  @Artist.one_to_one :first_album, :class=>@Album, :key=>:artist_id
39
- @Album.many_to_one :artist, :class=>@Artist
39
+ @Album.many_to_one :artist, :class=>@Artist, :reciprocal=>:albums
40
40
  @Album.many_to_many :tags, :class=>@Tag, :left_key=>:album_id, :right_key=>:tag_id, :join_table=>:at
41
41
  @Artist.nested_attributes :albums, :first_album, :destroy=>true, :remove=>true
42
42
  @Artist.nested_attributes :concerts, :destroy=>true, :remove=>true
@@ -419,7 +419,7 @@ describe "NestedAttributes plugin" do
419
419
  end
420
420
 
421
421
  it "should not attempt to validate nested attributes if the :validate=>false association option is used" do
422
- @Album.many_to_one :artist, :class=>@Artist, :validate=>false
422
+ @Album.many_to_one :artist, :class=>@Artist, :validate=>false, :reciprocal=>nil
423
423
  @Album.nested_attributes :artist, :tags, :destroy=>true, :remove=>true
424
424
  @Artist.class_eval do
425
425
  def validate
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "null_dataset extension" do
4
4
  before do
5
- @db = Sequel::mock(:fetch=>{:id=>1}, :autoid=>1, :numrows=>1, :columns=>[:id])
5
+ @db = Sequel::mock(:fetch=>{:id=>1}, :autoid=>1, :numrows=>1, :columns=>[:id]).extension(:null_dataset)
6
6
  @ds = @db[:table].nullify
7
7
  @i = 0
8
8
  @pr = proc{|*a| @i += 1}
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "A paginated dataset" do
4
4
  before do
5
- @d = Sequel::Dataset.new(nil)
5
+ @d = Sequel.mock.dataset.extension(:pagination)
6
6
  @d.meta_def(:count) {153}
7
7
 
8
8
  @paginated = @d.paginate(1, 20)
@@ -78,7 +78,7 @@ end
78
78
 
79
79
  describe "Dataset#each_page" do
80
80
  before do
81
- @d = Sequel::Dataset.new(nil).from(:items)
81
+ @d = Sequel.mock.dataset.from(:items).extension(:pagination)
82
82
  @d.meta_def(:count) {153}
83
83
  end
84
84
 
@@ -18,6 +18,14 @@ describe "Sequel::Postgres::HStoreOp" do
18
18
  @ds.literal(@h - Sequel.lit('a')).should == "(h - a)"
19
19
  end
20
20
 
21
+ it "#- should handle arrays" do
22
+ @ds.literal(@h - %w'a').should == "(h - ARRAY['a'])"
23
+ end
24
+
25
+ it "#- should handle hashes" do
26
+ @ds.literal(@h - {'a'=>'b'}).should == "(h - '\"a\"=>\"b\"'::hstore)"
27
+ end
28
+
21
29
  it "#- should return an HStoreOp" do
22
30
  @ds.literal((@h - :a)['a']).should == "((h - a) -> 'a')"
23
31
  end
@@ -26,6 +34,22 @@ describe "Sequel::Postgres::HStoreOp" do
26
34
  @ds.literal(@h['a']).should == "(h -> 'a')"
27
35
  end
28
36
 
37
+ it "#[] should handle arrays" do
38
+ @ds.literal(@h[%w'a']).should == "(h -> ARRAY['a'])"
39
+ end
40
+
41
+ it "#[] should return a PGArrayOp if given an array" do
42
+ @ds.literal(@h[%w'a'][0]).should == "(h -> ARRAY['a'])[0]"
43
+ end
44
+
45
+ it "#[] should return a PGArrayOp if given a PGArray" do
46
+ @ds.literal(@h[Sequel.pg_array(%w'a')][0]).should == "(h -> ARRAY['a'])[0]"
47
+ end
48
+
49
+ it "#[] should return a PGArrayOp if given a PGArrayOp" do
50
+ @ds.literal(@h[Sequel.pg_array_op(:a)][0]).should == "(h -> a)[0]"
51
+ end
52
+
29
53
  it "#[] should return a string expression" do
30
54
  @ds.literal(@h['a'] + 'b').should == "((h -> 'a') || 'b')"
31
55
  end
@@ -35,6 +59,11 @@ describe "Sequel::Postgres::HStoreOp" do
35
59
  @ds.literal(@h.merge(:h1)).should == "(h || h1)"
36
60
  end
37
61
 
62
+ it "#concat and #merge should handle hashes" do
63
+ @ds.literal(@h.concat('a'=>'b')).should == "(h || '\"a\"=>\"b\"'::hstore)"
64
+ @ds.literal(@h.merge('a'=>'b')).should == "(h || '\"a\"=>\"b\"'::hstore)"
65
+ end
66
+
38
67
  it "#concat should return an HStoreOp" do
39
68
  @ds.literal(@h.concat(:h1)['a']).should == "((h || h1) -> 'a')"
40
69
  end
@@ -43,18 +72,34 @@ describe "Sequel::Postgres::HStoreOp" do
43
72
  @ds.literal(@h.contain_all(:h1)).should == "(h ?& h1)"
44
73
  end
45
74
 
75
+ it "#contain_all handle arrays" do
76
+ @ds.literal(@h.contain_all(%w'h1')).should == "(h ?& ARRAY['h1'])"
77
+ end
78
+
46
79
  it "#contain_any should use the ?| operator" do
47
80
  @ds.literal(@h.contain_any(:h1)).should == "(h ?| h1)"
48
81
  end
49
82
 
83
+ it "#contain_any should handle arrays" do
84
+ @ds.literal(@h.contain_any(%w'h1')).should == "(h ?| ARRAY['h1'])"
85
+ end
86
+
50
87
  it "#contains should use the @> operator" do
51
88
  @ds.literal(@h.contains(:h1)).should == "(h @> h1)"
52
89
  end
53
90
 
91
+ it "#contains should handle hashes" do
92
+ @ds.literal(@h.contains('a'=>'b')).should == "(h @> '\"a\"=>\"b\"'::hstore)"
93
+ end
94
+
54
95
  it "#contained_by should use the <@ operator" do
55
96
  @ds.literal(@h.contained_by(:h1)).should == "(h <@ h1)"
56
97
  end
57
98
 
99
+ it "#contained_by should handle hashes" do
100
+ @ds.literal(@h.contained_by('a'=>'b')).should == "(h <@ '\"a\"=>\"b\"'::hstore)"
101
+ end
102
+
58
103
  it "#defined should use the defined function" do
59
104
  @ds.literal(@h.defined('a')).should == "defined(h, 'a')"
60
105
  end
@@ -63,6 +108,14 @@ describe "Sequel::Postgres::HStoreOp" do
63
108
  @ds.literal(@h.delete('a')).should == "delete(h, 'a')"
64
109
  end
65
110
 
111
+ it "#delete should handle arrays" do
112
+ @ds.literal(@h.delete(%w'a')).should == "delete(h, ARRAY['a'])"
113
+ end
114
+
115
+ it "#delete should handle hashes" do
116
+ @ds.literal(@h.delete('a'=>'b')).should == "delete(h, '\"a\"=>\"b\"'::hstore)"
117
+ end
118
+
66
119
  it "#delete should return an HStoreOp" do
67
120
  @ds.literal(@h.delete('a')['a']).should == "(delete(h, 'a') -> 'a')"
68
121
  end
@@ -88,6 +141,11 @@ describe "Sequel::Postgres::HStoreOp" do
88
141
  @ds.literal(@h.akeys).should == "akeys(h)"
89
142
  end
90
143
 
144
+ it "#keys and #akeys should return PGArrayOps" do
145
+ @ds.literal(@h.keys[0]).should == "akeys(h)[0]"
146
+ @ds.literal(@h.akeys[0]).should == "akeys(h)[0]"
147
+ end
148
+
91
149
  it "#populate should use the populate_record function" do
92
150
  @ds.literal(@h.populate(:a)).should == "populate_record(a, h)"
93
151
  end
@@ -104,6 +162,10 @@ describe "Sequel::Postgres::HStoreOp" do
104
162
  @ds.literal(@h.slice(:a)).should == "slice(h, a)"
105
163
  end
106
164
 
165
+ it "#slice should handle arrays" do
166
+ @ds.literal(@h.slice(%w'a')).should == "slice(h, ARRAY['a'])"
167
+ end
168
+
107
169
  it "#slice should return an HStoreOp" do
108
170
  @ds.literal(@h.slice(:a)['a']).should == "(slice(h, a) -> 'a')"
109
171
  end
@@ -116,15 +178,28 @@ describe "Sequel::Postgres::HStoreOp" do
116
178
  @ds.literal(@h.to_array).should == "hstore_to_array(h)"
117
179
  end
118
180
 
181
+ it "#to_array should return a PGArrayOp" do
182
+ @ds.literal(@h.to_array[0]).should == "hstore_to_array(h)[0]"
183
+ end
184
+
119
185
  it "#to_matrix should use the hstore_to_matrix function" do
120
186
  @ds.literal(@h.to_matrix).should == "hstore_to_matrix(h)"
121
187
  end
122
188
 
189
+ it "#to_matrix should return a PGArrayOp" do
190
+ @ds.literal(@h.to_matrix[0]).should == "hstore_to_matrix(h)[0]"
191
+ end
192
+
123
193
  it "#values and #avals should use the avals function" do
124
194
  @ds.literal(@h.values).should == "avals(h)"
125
195
  @ds.literal(@h.avals).should == "avals(h)"
126
196
  end
127
197
 
198
+ it "#values and #avals should return PGArrayOps" do
199
+ @ds.literal(@h.values[0]).should == "avals(h)[0]"
200
+ @ds.literal(@h.avals[0]).should == "avals(h)[0]"
201
+ end
202
+
128
203
  it "should have Sequel.hstore_op return HStoreOp instances as-is" do
129
204
  Sequel.hstore_op(@h).should equal(@h)
130
205
  end
@@ -27,7 +27,7 @@ describe "Sequel::Postgres::RangeOp" do
27
27
  @ds.literal(Sequel.pg_range(1..2, :numrange).op.lower).should == "lower('[1,2]'::numrange)"
28
28
  end
29
29
 
30
- it "should define methods for all of the the PostgreSQL range operators" do
30
+ it "should define methods for all of the PostgreSQL range operators" do
31
31
  @ds.literal(@h.contains(@h)).should == "(h @> h)"
32
32
  @ds.literal(@h.contained_by(@h)).should == "(h <@ h)"
33
33
  @ds.literal(@h.overlaps(@h)).should == "(h && h)"
@@ -36,12 +36,14 @@ describe "Sequel::Postgres::RangeOp" do
36
36
  @ds.literal(@h.ends_before(@h)).should == "(h &< h)"
37
37
  @ds.literal(@h.starts_after(@h)).should == "(h &> h)"
38
38
  @ds.literal(@h.adjacent_to(@h)).should == "(h -|- h)"
39
+ end
39
40
 
41
+ qspecify "should define methods for the deprecated PostgreSQL range operators" do
40
42
  @ds.literal(@h.starts_before(@h)).should == "(h &< h)"
41
43
  @ds.literal(@h.ends_after(@h)).should == "(h &> h)"
42
44
  end
43
45
 
44
- it "should define methods for all of the the PostgreSQL range functions" do
46
+ it "should define methods for all of the PostgreSQL range functions" do
45
47
  @ds.literal(@h.lower).should == "lower(h)"
46
48
  @ds.literal(@h.upper).should == "upper(h)"
47
49
  @ds.literal(@h.isempty).should == "isempty(h)"
@@ -57,6 +57,6 @@ describe "Sequel::Plugins::PgRow" do
57
57
  end
58
58
 
59
59
  it "should allow inserting just this model value" do
60
- @c2.insert_sql(@c.load(:street=>'123', :city=>'Bar')).should == "INSERT INTO company VALUES (ROW('123', 'Bar')::address)"
60
+ @c2.dataset.insert_sql(@c.load(:street=>'123', :city=>'Bar')).should == "INSERT INTO company VALUES (ROW('123', 'Bar')::address)"
61
61
  end
62
62
  end
@@ -7,7 +7,7 @@ describe "Dataset#print" do
7
7
  @output = StringIO.new
8
8
  @orig_stdout = $stdout
9
9
  $stdout = @output
10
- @dataset = Sequel.mock(:fetch=>[{:a=>1, :b=>2}, {:a=>3, :b=>4}, {:a=>5, :b=>6}])[:items]
10
+ @dataset = Sequel.mock(:fetch=>[{:a=>1, :b=>2}, {:a=>3, :b=>4}, {:a=>5, :b=>6}])[:items].extension(:pretty_table)
11
11
  end
12
12
 
13
13
  after do
@@ -2,7 +2,7 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "query_literals extension" do
4
4
  before do
5
- @ds = Sequel::Dataset.new(nil).from(:t).extension(:query_literals)
5
+ @ds = Sequel.mock.dataset.from(:t).extension(:query_literals)
6
6
  end
7
7
 
8
8
  it "should not use special support if given a block" do
@@ -1,8 +1,8 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
- describe "Database#dataset" do
3
+ describe "Database#query" do
4
4
  before do
5
- @db = Sequel::Database.new
5
+ @db = Sequel.mock.extension(:query)
6
6
  end
7
7
 
8
8
  specify "should delegate to Dataset#query if block is provided" do
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  describe "Dataset#query" do
16
16
  before do
17
- @d = Sequel::Dataset.new(nil)
17
+ @d = Sequel.mock.dataset.extension(:query)
18
18
  end
19
19
 
20
20
  specify "should allow cloning without arguments" do