ghost_dm-core 1.3.0.beta
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/.autotest +29 -0
- data/.document +5 -0
- data/.gitignore +35 -0
- data/.yardopts +1 -0
- data/Gemfile +65 -0
- data/LICENSE +20 -0
- data/README.md +269 -0
- data/Rakefile +4 -0
- data/dm-core.gemspec +24 -0
- data/lib/dm-core.rb +292 -0
- data/lib/dm-core/adapters.rb +222 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +237 -0
- data/lib/dm-core/adapters/in_memory_adapter.rb +113 -0
- data/lib/dm-core/associations/many_to_many.rb +499 -0
- data/lib/dm-core/associations/many_to_one.rb +290 -0
- data/lib/dm-core/associations/one_to_many.rb +348 -0
- data/lib/dm-core/associations/one_to_one.rb +86 -0
- data/lib/dm-core/associations/relationship.rb +663 -0
- data/lib/dm-core/backwards.rb +13 -0
- data/lib/dm-core/collection.rb +1515 -0
- data/lib/dm-core/core_ext/kernel.rb +23 -0
- data/lib/dm-core/core_ext/pathname.rb +6 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +7 -0
- data/lib/dm-core/model.rb +874 -0
- data/lib/dm-core/model/hook.rb +103 -0
- data/lib/dm-core/model/is.rb +32 -0
- data/lib/dm-core/model/property.rb +249 -0
- data/lib/dm-core/model/relationship.rb +378 -0
- data/lib/dm-core/model/scope.rb +89 -0
- data/lib/dm-core/property.rb +866 -0
- data/lib/dm-core/property/binary.rb +21 -0
- data/lib/dm-core/property/boolean.rb +20 -0
- data/lib/dm-core/property/class.rb +17 -0
- data/lib/dm-core/property/date.rb +10 -0
- data/lib/dm-core/property/date_time.rb +10 -0
- data/lib/dm-core/property/decimal.rb +36 -0
- data/lib/dm-core/property/discriminator.rb +44 -0
- data/lib/dm-core/property/float.rb +16 -0
- data/lib/dm-core/property/integer.rb +22 -0
- data/lib/dm-core/property/invalid_value_error.rb +22 -0
- data/lib/dm-core/property/lookup.rb +27 -0
- data/lib/dm-core/property/numeric.rb +38 -0
- data/lib/dm-core/property/object.rb +34 -0
- data/lib/dm-core/property/serial.rb +14 -0
- data/lib/dm-core/property/string.rb +38 -0
- data/lib/dm-core/property/text.rb +9 -0
- data/lib/dm-core/property/time.rb +10 -0
- data/lib/dm-core/property_set.rb +177 -0
- data/lib/dm-core/query.rb +1366 -0
- data/lib/dm-core/query/conditions/comparison.rb +911 -0
- data/lib/dm-core/query/conditions/operation.rb +721 -0
- data/lib/dm-core/query/direction.rb +36 -0
- data/lib/dm-core/query/operator.rb +35 -0
- data/lib/dm-core/query/path.rb +114 -0
- data/lib/dm-core/query/sort.rb +39 -0
- data/lib/dm-core/relationship_set.rb +72 -0
- data/lib/dm-core/repository.rb +226 -0
- data/lib/dm-core/resource.rb +1214 -0
- data/lib/dm-core/resource/persistence_state.rb +75 -0
- data/lib/dm-core/resource/persistence_state/clean.rb +40 -0
- data/lib/dm-core/resource/persistence_state/deleted.rb +30 -0
- data/lib/dm-core/resource/persistence_state/dirty.rb +96 -0
- data/lib/dm-core/resource/persistence_state/immutable.rb +34 -0
- data/lib/dm-core/resource/persistence_state/persisted.rb +29 -0
- data/lib/dm-core/resource/persistence_state/transient.rb +80 -0
- data/lib/dm-core/spec/lib/adapter_helpers.rb +64 -0
- data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
- data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
- data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
- data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
- data/lib/dm-core/spec/setup.rb +174 -0
- data/lib/dm-core/spec/shared/adapter_spec.rb +341 -0
- data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
- data/lib/dm-core/spec/shared/resource_spec.rb +1232 -0
- data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
- data/lib/dm-core/spec/shared/semipublic/property_spec.rb +176 -0
- data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
- data/lib/dm-core/support/assertions.rb +8 -0
- data/lib/dm-core/support/chainable.rb +18 -0
- data/lib/dm-core/support/deprecate.rb +12 -0
- data/lib/dm-core/support/descendant_set.rb +89 -0
- data/lib/dm-core/support/equalizer.rb +48 -0
- data/lib/dm-core/support/ext/array.rb +22 -0
- data/lib/dm-core/support/ext/blank.rb +25 -0
- data/lib/dm-core/support/ext/hash.rb +67 -0
- data/lib/dm-core/support/ext/module.rb +47 -0
- data/lib/dm-core/support/ext/object.rb +57 -0
- data/lib/dm-core/support/ext/string.rb +24 -0
- data/lib/dm-core/support/ext/try_dup.rb +12 -0
- data/lib/dm-core/support/hook.rb +405 -0
- data/lib/dm-core/support/inflections.rb +60 -0
- data/lib/dm-core/support/inflector/inflections.rb +211 -0
- data/lib/dm-core/support/inflector/methods.rb +151 -0
- data/lib/dm-core/support/lazy_array.rb +451 -0
- data/lib/dm-core/support/local_object_space.rb +13 -0
- data/lib/dm-core/support/logger.rb +201 -0
- data/lib/dm-core/support/mash.rb +176 -0
- data/lib/dm-core/support/naming_conventions.rb +90 -0
- data/lib/dm-core/support/ordered_set.rb +380 -0
- data/lib/dm-core/support/subject.rb +33 -0
- data/lib/dm-core/support/subject_set.rb +250 -0
- data/lib/dm-core/version.rb +3 -0
- data/script/performance.rb +275 -0
- data/script/profile.rb +218 -0
- data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
- data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +68 -0
- data/spec/public/associations/many_to_many_spec.rb +197 -0
- data/spec/public/associations/many_to_one_spec.rb +83 -0
- data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
- data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
- data/spec/public/associations/one_to_many_spec.rb +81 -0
- data/spec/public/associations/one_to_one_spec.rb +176 -0
- data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
- data/spec/public/collection_spec.rb +69 -0
- data/spec/public/finalize_spec.rb +76 -0
- data/spec/public/model/hook_spec.rb +246 -0
- data/spec/public/model/property_spec.rb +88 -0
- data/spec/public/model/relationship_spec.rb +1040 -0
- data/spec/public/model_spec.rb +462 -0
- data/spec/public/property/binary_spec.rb +41 -0
- data/spec/public/property/boolean_spec.rb +22 -0
- data/spec/public/property/class_spec.rb +28 -0
- data/spec/public/property/date_spec.rb +22 -0
- data/spec/public/property/date_time_spec.rb +22 -0
- data/spec/public/property/decimal_spec.rb +23 -0
- data/spec/public/property/discriminator_spec.rb +135 -0
- data/spec/public/property/float_spec.rb +22 -0
- data/spec/public/property/integer_spec.rb +22 -0
- data/spec/public/property/object_spec.rb +107 -0
- data/spec/public/property/serial_spec.rb +22 -0
- data/spec/public/property/string_spec.rb +22 -0
- data/spec/public/property/text_spec.rb +63 -0
- data/spec/public/property/time_spec.rb +22 -0
- data/spec/public/property_spec.rb +341 -0
- data/spec/public/resource_spec.rb +288 -0
- data/spec/public/sel_spec.rb +53 -0
- data/spec/public/setup_spec.rb +145 -0
- data/spec/public/shared/association_collection_shared_spec.rb +309 -0
- data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
- data/spec/public/shared/collection_shared_spec.rb +1667 -0
- data/spec/public/shared/finder_shared_spec.rb +1629 -0
- data/spec/rcov.opts +6 -0
- data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
- data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
- data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
- data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
- data/spec/semipublic/associations/relationship_spec.rb +200 -0
- data/spec/semipublic/associations_spec.rb +177 -0
- data/spec/semipublic/collection_spec.rb +110 -0
- data/spec/semipublic/model_spec.rb +96 -0
- data/spec/semipublic/property/binary_spec.rb +13 -0
- data/spec/semipublic/property/boolean_spec.rb +47 -0
- data/spec/semipublic/property/class_spec.rb +33 -0
- data/spec/semipublic/property/date_spec.rb +43 -0
- data/spec/semipublic/property/date_time_spec.rb +46 -0
- data/spec/semipublic/property/decimal_spec.rb +83 -0
- data/spec/semipublic/property/discriminator_spec.rb +19 -0
- data/spec/semipublic/property/float_spec.rb +82 -0
- data/spec/semipublic/property/integer_spec.rb +82 -0
- data/spec/semipublic/property/lookup_spec.rb +29 -0
- data/spec/semipublic/property/serial_spec.rb +13 -0
- data/spec/semipublic/property/string_spec.rb +13 -0
- data/spec/semipublic/property/text_spec.rb +31 -0
- data/spec/semipublic/property/time_spec.rb +50 -0
- data/spec/semipublic/property_spec.rb +114 -0
- data/spec/semipublic/query/conditions/comparison_spec.rb +1501 -0
- data/spec/semipublic/query/conditions/operation_spec.rb +1294 -0
- data/spec/semipublic/query/path_spec.rb +471 -0
- data/spec/semipublic/query_spec.rb +3682 -0
- data/spec/semipublic/resource/state/clean_spec.rb +88 -0
- data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
- data/spec/semipublic/resource/state/dirty_spec.rb +162 -0
- data/spec/semipublic/resource/state/immutable_spec.rb +105 -0
- data/spec/semipublic/resource/state/transient_spec.rb +162 -0
- data/spec/semipublic/resource/state_spec.rb +230 -0
- data/spec/semipublic/resource_spec.rb +23 -0
- data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +199 -0
- data/spec/semipublic/shared/resource_state_shared_spec.rb +79 -0
- data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/core_ext/hash.rb +10 -0
- data/spec/support/core_ext/inheritable_attributes.rb +46 -0
- data/spec/support/properties/huge_integer.rb +17 -0
- data/spec/unit/array_spec.rb +23 -0
- data/spec/unit/blank_spec.rb +73 -0
- data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
- data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
- data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
- data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
- data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
- data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
- data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
- data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
- data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
- data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
- data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
- data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
- data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
- data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
- data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
- data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
- data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
- data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
- data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
- data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
- data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
- data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
- data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
- data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
- data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
- data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
- data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
- data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
- data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
- data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
- data/spec/unit/hash_spec.rb +28 -0
- data/spec/unit/hook_spec.rb +1235 -0
- data/spec/unit/inflections_spec.rb +16 -0
- data/spec/unit/lazy_array_spec.rb +1949 -0
- data/spec/unit/mash_spec.rb +312 -0
- data/spec/unit/module_spec.rb +71 -0
- data/spec/unit/object_spec.rb +38 -0
- data/spec/unit/try_dup_spec.rb +46 -0
- data/tasks/ci.rake +1 -0
- data/tasks/spec.rake +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +365 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Spec
|
|
3
|
+
module CollectionHelpers
|
|
4
|
+
module GroupMethods
|
|
5
|
+
def self.extended(base)
|
|
6
|
+
base.class_inheritable_accessor :loaded
|
|
7
|
+
base.loaded = false
|
|
8
|
+
super
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def should_not_be_a_kicker(ivar = :@articles)
|
|
12
|
+
unless loaded
|
|
13
|
+
it 'should not be a kicker' do
|
|
14
|
+
instance_variable_get(ivar).should_not be_loaded
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
class CounterAdapter < DataMapper::Adapters::AbstractAdapter
|
|
2
|
+
instance_methods.each do |method|
|
|
3
|
+
next if method =~ /\A__/ ||
|
|
4
|
+
%w[ send class dup object_id kind_of? instance_of? respond_to? equal? freeze frozen? should should_not instance_variables instance_variable_set instance_variable_get instance_variable_defined? remove_instance_variable extend inspect copy_object ].include?(method.to_s)
|
|
5
|
+
undef_method method
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
attr_reader :counts
|
|
9
|
+
|
|
10
|
+
def kind_of?(klass)
|
|
11
|
+
super || @adapter.kind_of?(klass)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def instance_of?(klass)
|
|
15
|
+
super || @adapter.instance_of?(klass)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def respond_to?(method, include_private = false)
|
|
19
|
+
super || @adapter.respond_to?(method, include_private)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def initialize(adapter)
|
|
25
|
+
@counts = Hash.new { |hash, key| hash[key] = 0 }
|
|
26
|
+
@adapter = adapter
|
|
27
|
+
@count = 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def increment_count_for(method)
|
|
31
|
+
@counts[method] += 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def method_missing(method, *args, &block)
|
|
35
|
+
increment_count_for(method)
|
|
36
|
+
@adapter.send(method, *args, &block)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Spec
|
|
3
|
+
module PendingHelpers
|
|
4
|
+
|
|
5
|
+
def pending_if(*args)
|
|
6
|
+
message, boolean = parse_args(*args)
|
|
7
|
+
|
|
8
|
+
if boolean
|
|
9
|
+
pending(message) { yield }
|
|
10
|
+
else
|
|
11
|
+
yield
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def rescue_if(*args)
|
|
16
|
+
message, boolean = parse_args(*args)
|
|
17
|
+
|
|
18
|
+
if boolean
|
|
19
|
+
raised = nil
|
|
20
|
+
begin
|
|
21
|
+
yield
|
|
22
|
+
raised = false
|
|
23
|
+
rescue Exception
|
|
24
|
+
raised = true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
raise "should have raised: #{message || 'TODO'}" if raised == false
|
|
28
|
+
else
|
|
29
|
+
yield
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def parse_args(*args)
|
|
36
|
+
case args.map { |arg| arg.class }
|
|
37
|
+
when [ String, TrueClass ], [ String, FalseClass ] then args
|
|
38
|
+
when [ String, NilClass ] then [ args.first, false ]
|
|
39
|
+
when [ String ] then [ args.first, true ]
|
|
40
|
+
when [ TrueClass ], [ FalseClass ] then [ '', args.first ]
|
|
41
|
+
when [ NilClass ] then [ '', false ]
|
|
42
|
+
when [] then [ '', true ] # defaults
|
|
43
|
+
else
|
|
44
|
+
raise ArgumentError, "Invalid arguments: #{args.inspect}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Spec
|
|
3
|
+
|
|
4
|
+
module Helpers
|
|
5
|
+
def reset_raise_on_save_failure(object)
|
|
6
|
+
object.instance_eval do
|
|
7
|
+
if defined?(@raise_on_save_failure)
|
|
8
|
+
remove_instance_variable(:@raise_on_save_failure)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# global model cleanup
|
|
15
|
+
def self.cleanup_models
|
|
16
|
+
descendants = DataMapper::Model.descendants.to_a
|
|
17
|
+
|
|
18
|
+
while model = descendants.shift
|
|
19
|
+
model_name = model.name.to_s.strip
|
|
20
|
+
|
|
21
|
+
unless model_name.empty? || model_name[0] == ?#
|
|
22
|
+
parts = model_name.split('::')
|
|
23
|
+
constant_name = parts.pop.to_sym
|
|
24
|
+
base = parts.empty? ? Object : DataMapper::Ext::Object.full_const_get(parts.join('::'))
|
|
25
|
+
|
|
26
|
+
base.class_eval { remove_const(constant_name) if const_defined?(constant_name) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
remove_ivars(model)
|
|
30
|
+
model.instance_methods(false).each { |method| model.send(:undef_method, method) }
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
DataMapper::Model.descendants.clear
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.remove_ivars(object, instance_variables = object.instance_variables)
|
|
38
|
+
seen = {}
|
|
39
|
+
stack = instance_variables.map { |var| [ object, var ] }
|
|
40
|
+
|
|
41
|
+
while node = stack.pop
|
|
42
|
+
object, ivar = node
|
|
43
|
+
|
|
44
|
+
# skip "global" and non-DM objects
|
|
45
|
+
next if object.kind_of?(DataMapper::Logger) ||
|
|
46
|
+
object.kind_of?(DataMapper::DescendantSet) ||
|
|
47
|
+
object.kind_of?(DataMapper::Adapters::AbstractAdapter) ||
|
|
48
|
+
object.class.name[0, 13] == 'DataObjects::'
|
|
49
|
+
|
|
50
|
+
# skip classes and modules in the DataMapper namespace
|
|
51
|
+
next if object.kind_of?(Module) &&
|
|
52
|
+
!object.name.nil? &&
|
|
53
|
+
object.name[0, 12] == 'DataMapper::'
|
|
54
|
+
|
|
55
|
+
# skip when the ivar is no longer defined in the object
|
|
56
|
+
next unless object.instance_variable_defined?(ivar)
|
|
57
|
+
|
|
58
|
+
value = object.instance_variable_get(ivar)
|
|
59
|
+
|
|
60
|
+
# skip descendant sets
|
|
61
|
+
next if value.kind_of?(DataMapper::DescendantSet)
|
|
62
|
+
|
|
63
|
+
object.__send__(:remove_instance_variable, ivar) unless object.frozen?
|
|
64
|
+
|
|
65
|
+
# skip when the value was seen
|
|
66
|
+
next if seen.key?(value.object_id)
|
|
67
|
+
seen[value.object_id] = true
|
|
68
|
+
|
|
69
|
+
stack.concat value.instance_variables.map { |ivar| [ value, ivar ] }
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
require 'dm-core'
|
|
2
|
+
|
|
3
|
+
module DataMapper
|
|
4
|
+
module Spec
|
|
5
|
+
|
|
6
|
+
class << self
|
|
7
|
+
|
|
8
|
+
def root
|
|
9
|
+
@root ||= default_root
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def root=(path)
|
|
13
|
+
@root = Pathname(path)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
%w[setup setup! adapter adapter_name].each do |action|
|
|
17
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
18
|
+
def #{action}(kind = :default)
|
|
19
|
+
perform_action(kind, :#{action})
|
|
20
|
+
end
|
|
21
|
+
RUBY
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def configure
|
|
25
|
+
@configured = begin
|
|
26
|
+
setup_logger
|
|
27
|
+
require_plugins
|
|
28
|
+
require_spec_adapter
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def configured?
|
|
34
|
+
@configured
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def setup_logger
|
|
38
|
+
if log = ENV['LOG']
|
|
39
|
+
logger = DataMapper::Logger.new(log_stream(log), :debug)
|
|
40
|
+
logger.auto_flush = true
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def require_spec_adapter
|
|
45
|
+
desired_adapter = (ENV['ADAPTER'] || ENV['ADAPTERS'])
|
|
46
|
+
if desired_adapter.nil? || desired_adapter == 'in_memory'
|
|
47
|
+
ENV['ADAPTER_SUPPORTS'] = 'all'
|
|
48
|
+
Adapters.use(Adapters::InMemoryAdapter)
|
|
49
|
+
else
|
|
50
|
+
require "dm-#{desired_adapter}-adapter/spec/setup"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def require_plugins
|
|
55
|
+
adapter = (ENV['ADAPTER'] || ENV['ADAPTERS'])
|
|
56
|
+
plugins = ENV['PLUGINS'] || ENV['PLUGIN']
|
|
57
|
+
plugins = plugins.to_s.split(/[,\s]+/)
|
|
58
|
+
unless adapter == 'in_memory'
|
|
59
|
+
plugins.push('dm-migrations')
|
|
60
|
+
end
|
|
61
|
+
plugins.uniq.each { |plugin| require plugin }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def spec_adapters
|
|
65
|
+
@spec_adapters ||= {}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def perform_action(kind, action)
|
|
71
|
+
configure unless configured?
|
|
72
|
+
spec_adapters[kind].send(action)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def default_root
|
|
76
|
+
Pathname(Dir.pwd).join('spec')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def log_stream(log)
|
|
80
|
+
log == 'file' ? root.join('log/dm.log') : $stdout
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
module Adapters
|
|
86
|
+
|
|
87
|
+
def self.use(adapter_class)
|
|
88
|
+
Spec.spec_adapters[:default] = adapter_class.new(:default)
|
|
89
|
+
Spec.spec_adapters[:alternate] = adapter_class.new(:alternate)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
class Adapter
|
|
93
|
+
|
|
94
|
+
attr_reader :name
|
|
95
|
+
|
|
96
|
+
def initialize(name)
|
|
97
|
+
@name = name.to_sym
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def adapter
|
|
101
|
+
@adapter ||= setup!
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
alias_method :setup, :adapter
|
|
105
|
+
|
|
106
|
+
def setup!
|
|
107
|
+
adapter = DataMapper.setup(name, connection_uri)
|
|
108
|
+
test_connection(adapter)
|
|
109
|
+
adapter
|
|
110
|
+
rescue Exception => e
|
|
111
|
+
puts "Could not connect to the database using '#{connection_uri}' because of: #{e.inspect}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def adapter_name
|
|
115
|
+
@adapter_name ||= infer_adapter_name
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def connection_uri
|
|
119
|
+
"#{adapter_name}://#{username}:#{password}@#{host}/#{storage_name}"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def storage_name
|
|
123
|
+
send("#{name}_storage_name")
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def default_storage_name
|
|
127
|
+
"datamapper_default_tests"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def alternate_storage_name
|
|
131
|
+
"datamapper_alternate_tests"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def username
|
|
135
|
+
ENV.fetch('DM_DB_USER', 'datamapper')
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def password
|
|
139
|
+
ENV.fetch('DM_DB_PASSWORD', 'datamapper')
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def host
|
|
143
|
+
ENV.fetch('DM_DB_HOST', 'localhost')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Test the connection
|
|
147
|
+
#
|
|
148
|
+
# Overwrite this method if you need to perform custom connection testing
|
|
149
|
+
#
|
|
150
|
+
# @raise [Exception]
|
|
151
|
+
def test_connection(adapter)
|
|
152
|
+
if adapter.respond_to?(:select)
|
|
153
|
+
adapter.select('SELECT 1')
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
private
|
|
158
|
+
|
|
159
|
+
def infer_adapter_name
|
|
160
|
+
demodulized = DataMapper::Inflector.demodulize(self.class.name.chomp('Adapter'))
|
|
161
|
+
DataMapper::Inflector.underscore(demodulized).freeze
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
class InMemoryAdapter < Adapter
|
|
167
|
+
def connection_uri
|
|
168
|
+
{ :adapter => :in_memory }
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
share_examples_for 'An Adapter' do
|
|
2
|
+
|
|
3
|
+
def self.adapter_supports?(*methods)
|
|
4
|
+
|
|
5
|
+
# FIXME obviously this needs a real fix!
|
|
6
|
+
# --------------------------------------
|
|
7
|
+
# Probably, delaying adapter_supports?
|
|
8
|
+
# to be executed after DataMapper.setup
|
|
9
|
+
# has been called will solve our current
|
|
10
|
+
# problem with described_type() being nil
|
|
11
|
+
# for as long as DataMapper.setup wasn't
|
|
12
|
+
# called
|
|
13
|
+
return true if ENV['ADAPTER_SUPPORTS'] == 'all'
|
|
14
|
+
|
|
15
|
+
methods.all? do |method|
|
|
16
|
+
# TODO: figure out a way to see if the instance method is only inherited
|
|
17
|
+
# from the Abstract Adapter, and not defined in it's class. If that is
|
|
18
|
+
# the case return false
|
|
19
|
+
|
|
20
|
+
# CRUD methods can be inherited from parent class
|
|
21
|
+
described_type.instance_methods.any? { |instance_method| method.to_s == instance_method.to_s }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Hack to detect cases a let(:heffalump_model) is not present
|
|
26
|
+
unless instance_methods.map(&:to_s).include?('heffalump_model')
|
|
27
|
+
# This is the default Heffalup model. You can replace it with your own
|
|
28
|
+
# (using let/let!) # but # be shure the replacement provides the required
|
|
29
|
+
# properties.
|
|
30
|
+
let(:heffalump_model) do
|
|
31
|
+
model = Class.new do
|
|
32
|
+
include DataMapper::Resource
|
|
33
|
+
property :id, DataMapper::Property::Serial
|
|
34
|
+
property :color, DataMapper::Property::String
|
|
35
|
+
property :num_spots, DataMapper::Property::Integer
|
|
36
|
+
property :striped, DataMapper::Property::Boolean
|
|
37
|
+
|
|
38
|
+
# This is needed for DataMapper.finalize
|
|
39
|
+
def self.name; 'Heffalump'; end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
DataMapper.finalize
|
|
43
|
+
|
|
44
|
+
model
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
before :all do
|
|
49
|
+
raise '+#adapter+ should be defined in a let(:adapter) block' unless respond_to?(:adapter)
|
|
50
|
+
raise '+#repository+ should be defined in a let(:repository) block' unless respond_to?(:repository)
|
|
51
|
+
|
|
52
|
+
DataMapper.finalize
|
|
53
|
+
|
|
54
|
+
# create all tables and constraints before each spec
|
|
55
|
+
if repository.respond_to?(:auto_migrate!)
|
|
56
|
+
heffalump_model.auto_migrate!
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if adapter_supports?(:create)
|
|
61
|
+
describe '#create' do
|
|
62
|
+
it 'should not raise any errors' do
|
|
63
|
+
lambda {
|
|
64
|
+
heffalump_model.create(:color => 'peach')
|
|
65
|
+
}.should_not raise_error
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should set the identity field for the resource' do
|
|
69
|
+
heffalump = heffalump_model.new(:color => 'peach')
|
|
70
|
+
heffalump.id.should be_nil
|
|
71
|
+
heffalump.save
|
|
72
|
+
heffalump.id.should_not be_nil
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
else
|
|
76
|
+
it 'needs to support #create'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
if adapter_supports?(:read)
|
|
80
|
+
describe '#read' do
|
|
81
|
+
before :all do
|
|
82
|
+
@heffalump = heffalump_model.create(:color => 'brownish hue')
|
|
83
|
+
#just going to borrow this, so I can check the return values
|
|
84
|
+
@query = heffalump_model.all.query
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'should not raise any errors' do
|
|
88
|
+
lambda {
|
|
89
|
+
heffalump_model.all()
|
|
90
|
+
}.should_not raise_error
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'should return stuff' do
|
|
94
|
+
heffalump_model.all.should be_include(@heffalump)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
else
|
|
98
|
+
it 'needs to support #read'
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
if adapter_supports?(:update)
|
|
102
|
+
describe '#update' do
|
|
103
|
+
before do
|
|
104
|
+
@heffalump = heffalump_model.create(:color => 'indigo')
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'should not raise any errors' do
|
|
108
|
+
lambda {
|
|
109
|
+
@heffalump.color = 'violet'
|
|
110
|
+
@heffalump.save
|
|
111
|
+
}.should_not raise_error
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it 'should not alter the identity field' do
|
|
115
|
+
id = @heffalump.id
|
|
116
|
+
@heffalump.color = 'violet'
|
|
117
|
+
@heffalump.save
|
|
118
|
+
@heffalump.id.should == id
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'should update altered fields' do
|
|
122
|
+
@heffalump.color = 'violet'
|
|
123
|
+
@heffalump.save
|
|
124
|
+
heffalump_model.get(*@heffalump.key).color.should == 'violet'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'should not alter other fields' do
|
|
128
|
+
color = @heffalump.color
|
|
129
|
+
@heffalump.num_spots = 3
|
|
130
|
+
@heffalump.save
|
|
131
|
+
heffalump_model.get(*@heffalump.key).color.should == color
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
else
|
|
135
|
+
it 'needs to support #update'
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
if adapter_supports?(:delete)
|
|
139
|
+
describe '#delete' do
|
|
140
|
+
before do
|
|
141
|
+
@heffalump = heffalump_model.create(:color => 'forest green')
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'should not raise any errors' do
|
|
145
|
+
lambda {
|
|
146
|
+
@heffalump.destroy
|
|
147
|
+
}.should_not raise_error
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it 'should delete the requested resource' do
|
|
151
|
+
id = @heffalump.id
|
|
152
|
+
@heffalump.destroy
|
|
153
|
+
heffalump_model.get(id).should be_nil
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
else
|
|
157
|
+
it 'needs to support #delete'
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
if adapter_supports?(:read, :create)
|
|
161
|
+
describe 'query matching' do
|
|
162
|
+
before :all do
|
|
163
|
+
@red = heffalump_model.create(:color => 'red')
|
|
164
|
+
@two = heffalump_model.create(:num_spots => 2)
|
|
165
|
+
@five = heffalump_model.create(:num_spots => 5)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
describe 'conditions' do
|
|
169
|
+
describe 'eql' do
|
|
170
|
+
it 'should be able to search for objects included in an inclusive range of values' do
|
|
171
|
+
heffalump_model.all(:num_spots => 1..5).should be_include(@five)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'should be able to search for objects included in an exclusive range of values' do
|
|
175
|
+
heffalump_model.all(:num_spots => 1...6).should be_include(@five)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it 'should not be able to search for values not included in an inclusive range of values' do
|
|
179
|
+
heffalump_model.all(:num_spots => 1..4).should_not be_include(@five)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it 'should not be able to search for values not included in an exclusive range of values' do
|
|
183
|
+
heffalump_model.all(:num_spots => 1...5).should_not be_include(@five)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
describe 'not' do
|
|
188
|
+
it 'should be able to search for objects with not equal value' do
|
|
189
|
+
heffalump_model.all(:color.not => 'red').should_not be_include(@red)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it 'should include objects that are not like the value' do
|
|
193
|
+
heffalump_model.all(:color.not => 'black').should be_include(@red)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it 'should be able to search for objects with not nil value' do
|
|
197
|
+
heffalump_model.all(:color.not => nil).should be_include(@red)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it 'should not include objects with a nil value' do
|
|
201
|
+
heffalump_model.all(:color.not => nil).should_not be_include(@two)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it 'should be able to search for object with a nil value using required properties' do
|
|
205
|
+
heffalump_model.all(:id.not => nil).should == [ @red, @two, @five ]
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
it 'should be able to search for objects not in an empty list (match all)' do
|
|
209
|
+
heffalump_model.all(:color.not => []).should == [ @red, @two, @five ]
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it 'should be able to search for objects in an empty list and another OR condition (match none on the empty list)' do
|
|
213
|
+
heffalump_model.all(
|
|
214
|
+
:conditions => DataMapper::Query::Conditions::Operation.new(
|
|
215
|
+
:or,
|
|
216
|
+
DataMapper::Query::Conditions::Comparison.new(:in, heffalump_model.properties[:color], []),
|
|
217
|
+
DataMapper::Query::Conditions::Comparison.new(:in, heffalump_model.properties[:num_spots], [5])
|
|
218
|
+
)
|
|
219
|
+
).should == [ @five ]
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it 'should be able to search for objects not included in an array of values' do
|
|
223
|
+
heffalump_model.all(:num_spots.not => [ 1, 3, 5, 7 ]).should be_include(@two)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it 'should be able to search for objects not included in an array of values' do
|
|
227
|
+
heffalump_model.all(:num_spots.not => [ 1, 3, 5, 7 ]).should_not be_include(@five)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
it 'should be able to search for objects not included in an inclusive range of values' do
|
|
231
|
+
heffalump_model.all(:num_spots.not => 1..4).should be_include(@five)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it 'should be able to search for objects not included in an exclusive range of values' do
|
|
235
|
+
heffalump_model.all(:num_spots.not => 1...5).should be_include(@five)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it 'should not be able to search for values not included in an inclusive range of values' do
|
|
239
|
+
heffalump_model.all(:num_spots.not => 1..5).should_not be_include(@five)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'should not be able to search for values not included in an exclusive range of values' do
|
|
243
|
+
heffalump_model.all(:num_spots.not => 1...6).should_not be_include(@five)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
describe 'like' do
|
|
248
|
+
it 'should be able to search for objects that match value' do
|
|
249
|
+
heffalump_model.all(:color.like => '%ed').should be_include(@red)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it 'should not search for objects that do not match the value' do
|
|
253
|
+
heffalump_model.all(:color.like => '%blak%').should_not be_include(@red)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
describe 'regexp' do
|
|
258
|
+
before do
|
|
259
|
+
if (defined?(DataMapper::Adapters::SqliteAdapter) && adapter.kind_of?(DataMapper::Adapters::SqliteAdapter) ||
|
|
260
|
+
defined?(DataMapper::Adapters::SqlserverAdapter) && adapter.kind_of?(DataMapper::Adapters::SqlserverAdapter))
|
|
261
|
+
pending 'delegate regexp matches to same system that the InMemory and YAML adapters use'
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it 'should be able to search for objects that match value' do
|
|
266
|
+
heffalump_model.all(:color => /ed/).should be_include(@red)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
it 'should not be able to search for objects that do not match the value' do
|
|
270
|
+
heffalump_model.all(:color => /blak/).should_not be_include(@red)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it 'should be able to do a negated search for objects that match value' do
|
|
274
|
+
heffalump_model.all(:color.not => /blak/).should be_include(@red)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it 'should not be able to do a negated search for objects that do not match value' do
|
|
278
|
+
heffalump_model.all(:color.not => /ed/).should_not be_include(@red)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
describe 'gt' do
|
|
284
|
+
it 'should be able to search for objects with value greater than' do
|
|
285
|
+
heffalump_model.all(:num_spots.gt => 1).should be_include(@two)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it 'should not find objects with a value less than' do
|
|
289
|
+
heffalump_model.all(:num_spots.gt => 3).should_not be_include(@two)
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
describe 'gte' do
|
|
294
|
+
it 'should be able to search for objects with value greater than' do
|
|
295
|
+
heffalump_model.all(:num_spots.gte => 1).should be_include(@two)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
it 'should be able to search for objects with values equal to' do
|
|
299
|
+
heffalump_model.all(:num_spots.gte => 2).should be_include(@two)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it 'should not find objects with a value less than' do
|
|
303
|
+
heffalump_model.all(:num_spots.gte => 3).should_not be_include(@two)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
describe 'lt' do
|
|
308
|
+
it 'should be able to search for objects with value less than' do
|
|
309
|
+
heffalump_model.all(:num_spots.lt => 3).should be_include(@two)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it 'should not find objects with a value less than' do
|
|
313
|
+
heffalump_model.all(:num_spots.gt => 2).should_not be_include(@two)
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
describe 'lte' do
|
|
318
|
+
it 'should be able to search for objects with value less than' do
|
|
319
|
+
heffalump_model.all(:num_spots.lte => 3).should be_include(@two)
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
it 'should be able to search for objects with values equal to' do
|
|
323
|
+
heffalump_model.all(:num_spots.lte => 2).should be_include(@two)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
it 'should not find objects with a value less than' do
|
|
327
|
+
heffalump_model.all(:num_spots.lte => 1).should_not be_include(@two)
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
describe 'limits' do
|
|
333
|
+
it 'should be able to limit the objects' do
|
|
334
|
+
heffalump_model.all(:limit => 2).length.should == 2
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
else
|
|
339
|
+
it 'needs to support #read and #create to test query matching'
|
|
340
|
+
end
|
|
341
|
+
end
|