dm-core 0.10.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/.autotest +29 -0
  2. data/.document +5 -0
  3. data/.gitignore +27 -0
  4. data/LICENSE +20 -0
  5. data/{README.txt → README.rdoc} +14 -3
  6. data/Rakefile +23 -22
  7. data/VERSION +1 -0
  8. data/dm-core.gemspec +201 -10
  9. data/lib/dm-core.rb +32 -23
  10. data/lib/dm-core/adapters.rb +0 -1
  11. data/lib/dm-core/adapters/data_objects_adapter.rb +230 -151
  12. data/lib/dm-core/adapters/mysql_adapter.rb +7 -8
  13. data/lib/dm-core/adapters/oracle_adapter.rb +39 -59
  14. data/lib/dm-core/adapters/postgres_adapter.rb +0 -1
  15. data/lib/dm-core/adapters/sqlite3_adapter.rb +5 -0
  16. data/lib/dm-core/adapters/sqlserver_adapter.rb +114 -0
  17. data/lib/dm-core/adapters/yaml_adapter.rb +0 -5
  18. data/lib/dm-core/associations/many_to_many.rb +118 -56
  19. data/lib/dm-core/associations/many_to_one.rb +48 -21
  20. data/lib/dm-core/associations/one_to_many.rb +8 -30
  21. data/lib/dm-core/associations/one_to_one.rb +1 -5
  22. data/lib/dm-core/associations/relationship.rb +89 -97
  23. data/lib/dm-core/collection.rb +299 -184
  24. data/lib/dm-core/core_ext/enumerable.rb +28 -0
  25. data/lib/dm-core/core_ext/kernel.rb +0 -2
  26. data/lib/dm-core/migrations.rb +314 -170
  27. data/lib/dm-core/model.rb +97 -66
  28. data/lib/dm-core/model/descendant_set.rb +1 -1
  29. data/lib/dm-core/model/hook.rb +0 -3
  30. data/lib/dm-core/model/property.rb +7 -10
  31. data/lib/dm-core/model/relationship.rb +79 -26
  32. data/lib/dm-core/model/scope.rb +3 -4
  33. data/lib/dm-core/property.rb +152 -90
  34. data/lib/dm-core/property_set.rb +18 -37
  35. data/lib/dm-core/query.rb +452 -153
  36. data/lib/dm-core/query/conditions/comparison.rb +266 -173
  37. data/lib/dm-core/query/conditions/operation.rb +499 -57
  38. data/lib/dm-core/query/direction.rb +0 -3
  39. data/lib/dm-core/query/operator.rb +0 -4
  40. data/lib/dm-core/query/path.rb +10 -12
  41. data/lib/dm-core/query/sort.rb +4 -10
  42. data/lib/dm-core/repository.rb +10 -6
  43. data/lib/dm-core/resource.rb +343 -148
  44. data/lib/dm-core/spec/adapter_shared_spec.rb +17 -1
  45. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +277 -17
  46. data/lib/dm-core/support/chainable.rb +0 -2
  47. data/lib/dm-core/support/equalizer.rb +27 -3
  48. data/lib/dm-core/transaction.rb +75 -75
  49. data/lib/dm-core/type.rb +19 -5
  50. data/lib/dm-core/types/discriminator.rb +4 -4
  51. data/lib/dm-core/types/object.rb +2 -7
  52. data/lib/dm-core/types/paranoid_boolean.rb +8 -2
  53. data/lib/dm-core/types/paranoid_datetime.rb +8 -2
  54. data/lib/dm-core/version.rb +1 -1
  55. data/script/performance.rb +7 -7
  56. data/script/profile.rb +6 -6
  57. data/spec/lib/collection_helpers.rb +2 -2
  58. data/spec/lib/pending_helpers.rb +22 -3
  59. data/spec/lib/rspec_immediate_feedback_formatter.rb +1 -0
  60. data/spec/public/associations/many_to_many_spec.rb +6 -4
  61. data/spec/public/associations/many_to_one_spec.rb +10 -1
  62. data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +39 -0
  63. data/spec/public/associations/one_to_many_spec.rb +4 -3
  64. data/spec/public/associations/one_to_one_spec.rb +19 -1
  65. data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +45 -0
  66. data/spec/public/collection_spec.rb +4 -3
  67. data/spec/public/migrations_spec.rb +144 -0
  68. data/spec/public/model/relationship_spec.rb +115 -55
  69. data/spec/public/model_spec.rb +13 -13
  70. data/spec/public/property/object_spec.rb +106 -0
  71. data/spec/public/property_spec.rb +18 -14
  72. data/spec/public/resource_spec.rb +10 -1
  73. data/spec/public/sel_spec.rb +16 -49
  74. data/spec/public/setup_spec.rb +1 -1
  75. data/spec/public/shared/association_collection_shared_spec.rb +6 -14
  76. data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
  77. data/spec/public/shared/collection_shared_spec.rb +214 -217
  78. data/spec/public/shared/finder_shared_spec.rb +259 -365
  79. data/spec/public/shared/resource_shared_spec.rb +524 -248
  80. data/spec/public/transaction_spec.rb +27 -3
  81. data/spec/public/types/discriminator_spec.rb +1 -1
  82. data/spec/rcov.opts +6 -0
  83. data/spec/semipublic/adapters/sqlserver_adapter_spec.rb +17 -0
  84. data/spec/semipublic/associations/many_to_one_spec.rb +3 -20
  85. data/spec/semipublic/associations_spec.rb +2 -2
  86. data/spec/semipublic/collection_spec.rb +0 -32
  87. data/spec/semipublic/model_spec.rb +96 -0
  88. data/spec/semipublic/property_spec.rb +3 -3
  89. data/spec/semipublic/query/conditions/comparison_spec.rb +1719 -0
  90. data/spec/semipublic/query/conditions/operation_spec.rb +1292 -0
  91. data/spec/semipublic/query_spec.rb +1285 -144
  92. data/spec/semipublic/resource_spec.rb +0 -24
  93. data/spec/semipublic/shared/resource_shared_spec.rb +103 -38
  94. data/spec/spec.opts +1 -1
  95. data/spec/spec_helper.rb +15 -6
  96. data/tasks/ci.rake +1 -0
  97. data/tasks/metrics.rake +37 -0
  98. data/tasks/spec.rake +41 -0
  99. data/tasks/yard.rake +9 -0
  100. data/tasks/yardstick.rake +19 -0
  101. metadata +99 -29
  102. data/CONTRIBUTING +0 -51
  103. data/FAQ +0 -93
  104. data/History.txt +0 -27
  105. data/MIT-LICENSE +0 -22
  106. data/Manifest.txt +0 -121
  107. data/QUICKLINKS +0 -11
  108. data/SPECS +0 -35
  109. data/TODO +0 -1
  110. data/spec/semipublic/query/conditions_spec.rb +0 -528
  111. data/tasks/ci.rb +0 -24
  112. data/tasks/dm.rb +0 -58
  113. data/tasks/doc.rb +0 -17
  114. data/tasks/gemspec.rb +0 -23
  115. data/tasks/hoe.rb +0 -45
  116. data/tasks/install.rb +0 -18
data/CONTRIBUTING DELETED
@@ -1,51 +0,0 @@
1
- # NOTE: This is a work in progress. As of July 24, it applies only to dm-core.
2
-
3
- # Contributing to Edge DataMapper
4
-
5
- We have now implemented Hoe throughout the DataMapper suite, so there will be a
6
- handful of new procedures for contributing to our git repositories. I'll give
7
- you a run through of how to set up your machine, and then provide a few
8
- commands that should be run before committing or pushing changes.
9
-
10
- ## Installing and configuring Hoe
11
-
12
- The first step is to install hoe. You'll need at least version 1.7.0.
13
-
14
- (sudo) gem install hoe --include-dependencies
15
-
16
- Now you'll need to configure hoe. You'll need to run this from inside of
17
- dm-core, or one of the other DataMapper projects.
18
-
19
- rake config_hoe
20
-
21
- The only thing you should need to change is the exclude regular expression,
22
- which needs to look like this:
23
-
24
- exclude: !ruby/regexp /tmp$|CVS|\.svn|\.git|.+\.gemspec/
25
-
26
- Now you have the correct setup for contributing.
27
-
28
- ## Before committing changes
29
-
30
- Before you commit changes, you must verify that `Manifest.txt` (the file which
31
- contains the names of every file to be included in a gem release) and
32
- `[project-name].gemspec` are up to date. We have create a rake task to make
33
- this easy:
34
-
35
- rake gemspec
36
-
37
- This will check `Manifest.txt` (using Hoe's `rake check_manifest`) to ensure
38
- there are no differences between the files in the project, and those listed in
39
- the manifest. If there is a difference, it will display a warning and a list of
40
- the differences in `diff` format.
41
-
42
- If the changes in the diff are correct, then you can run the following command
43
- to update the manifest.
44
-
45
- rake check_manifest | patch
46
-
47
- If there are files you do not want added to the manifest, then you should
48
- remove the files from the project, and then run `rake gemspec` again.
49
-
50
- If `rake gemspec` says it was successful, then you can proceed with committing
51
- and pushing your changes.
data/FAQ DELETED
@@ -1,93 +0,0 @@
1
- :include:QUICKLINKS
2
-
3
- = FAQ
4
-
5
- === So where's my :id column?
6
-
7
- DataMapper will NOT create an auto-incrementing <tt>:id</tt> key for you
8
- automatically, so you'll need to either explicitly create one with
9
-
10
- property :id, Serial
11
-
12
- You can choose to use a natural key by doing
13
-
14
- property :slug, String, :key => true
15
-
16
- Remember, DataMapper supports multiple keys ("composite keys"), so if your
17
- model has two or more keys, no big deal
18
-
19
- property :store_id, Integer, :key => true
20
- property :invoice_id, Integer, :key => true
21
-
22
- === How do I make a model paranoid?
23
-
24
- Create a property and make it a ParanoidDateTime or ParanoidBoolean type.
25
-
26
- property :deleted_at, ParanoidDateTime
27
- property :deleted, ParanoidBoolean
28
-
29
- All of your calls to <tt>##all()</tt>, <tt>##first()</tt> will be scoped
30
- with <tt>:deleted_at => nil</tt> or <tt>:deleted => false</tt>. Plus,
31
- you won't see deleted objects in your associations.
32
-
33
- === Does DataMapper do Single Table Inheritance?
34
-
35
- This is what the Discriminator data-type is for:
36
-
37
- class Person
38
- include DataMapper::Resource
39
-
40
- property :id, Serial
41
- property :type, Discriminator ## other shared properties here
42
- end
43
-
44
- class Salesperson < Person; end
45
-
46
- You can claim a column to have the type <tt>Discriminator</tt> and DataMapper will
47
- automatically drop the class name of the inherited classes into that field of
48
- the data-store.
49
-
50
- === How do I run my own commands?
51
-
52
- repository.adapter.query("SELECT * FROM users WHERE clue > 0")
53
- repository(:integration).adapter.query("SELECT * FROM users WHERE clue > 0")
54
-
55
- This does not return any Users (har har), but rather Struct's that will quack
56
- like Users. They'll be read-only as well.
57
-
58
- <tt>repository.adapter.query</tt> shouldn't be used if you aren't expecting a result set
59
- back. If you want to just execute something against the database, use
60
- <tt>repository.adapter.execute</tt> instead.
61
-
62
-
63
- === Can I get an query log of what DataMapper is issuing?
64
-
65
- An example of how to modify an existing logger:
66
-
67
- DataMapper.logger.set_log(STDOUT, :debug)
68
-
69
- An example of how to create new logger:
70
-
71
- DataMapper::Logger.new(STDOUT, :info)
72
-
73
- To send a message to the DataMapper logger:
74
-
75
- DataMapper.logger.debug("something")
76
- DataMapper.logger.info ("something")
77
- DataMapper.logger.warn ("something")
78
- DataMapper.logger.error("something")
79
- DataMapper.logger.fatal("something")
80
-
81
-
82
- === I want to run the specs, but I have a custom database setup
83
-
84
- For example, if you installed MySQL using MacPorts, your socket may be located
85
- at /opt/local/var/run/mysql5/mysqld.sock instead of /tmp/mysql.sock
86
-
87
- In that case, setup an environment variable in your shell before running the
88
- specs:
89
- export MYSQL_SPEC_URI="mysql://localhost/dm_core_test?socket=/opt/local/var/run/mysql5/mysqld.sock"
90
- rake spec
91
-
92
- Using another kind of database? Note that spec_helper.rb will also look for
93
- SQLITE3_SPEC_URI AND POSTGRES_SPEC_URI.
data/History.txt DELETED
@@ -1,27 +0,0 @@
1
- === 0.10.1 / 2009-09-30
2
-
3
- * 4 minor enhancements:
4
-
5
- * On Ruby 1.8.7+ allow #pop and #shift in Collection to work with
6
- multiple entries.
7
- * Added NullOperation condition
8
- * Added Resource#destroyed?
9
- * Updated ManyToMany::Collection#intermediaries to be public
10
-
11
- * 6 bug fixes:
12
-
13
- * Fixed Query::Path to work with .like
14
- * Replaced usage of base64 lib with pack/unpack
15
- * Ensure the correct ordering of links for more complex joins
16
- * Simplified SELECT query generation
17
- * Simplified Relationship inheritance by subclasses
18
- * Ensure Property.new options allow an Array of Symbols for :unique,
19
- and :unique_index
20
-
21
- === 0.10.0 / 2009-09-15
22
-
23
- * Countless enhancements:
24
-
25
- * Total rewrite of most of dm-core, including YARD docs for more
26
- than half the methods and ~90% coverage of code. More to be done
27
- but this is a great start.
data/MIT-LICENSE DELETED
@@ -1,22 +0,0 @@
1
- Copyright (c) 2007, 2008, 2009 Sam Smoot, Dan Kubb
2
-
3
- Permission is hereby granted, free of charge, to any person
4
- obtaining a copy of this software and associated documentation
5
- files (the "Software"), to deal in the Software without
6
- restriction, including without limitation the rights to use,
7
- copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the
9
- Software is furnished to do so, subject to the following
10
- conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt DELETED
@@ -1,121 +0,0 @@
1
- .autotest
2
- .gitignore
3
- CONTRIBUTING
4
- FAQ
5
- History.txt
6
- MIT-LICENSE
7
- Manifest.txt
8
- QUICKLINKS
9
- README.txt
10
- Rakefile
11
- SPECS
12
- TODO
13
- deps.rip
14
- dm-core.gemspec
15
- lib/dm-core.rb
16
- lib/dm-core/adapters.rb
17
- lib/dm-core/adapters/abstract_adapter.rb
18
- lib/dm-core/adapters/data_objects_adapter.rb
19
- lib/dm-core/adapters/in_memory_adapter.rb
20
- lib/dm-core/adapters/mysql_adapter.rb
21
- lib/dm-core/adapters/oracle_adapter.rb
22
- lib/dm-core/adapters/postgres_adapter.rb
23
- lib/dm-core/adapters/sqlite3_adapter.rb
24
- lib/dm-core/adapters/yaml_adapter.rb
25
- lib/dm-core/associations/many_to_many.rb
26
- lib/dm-core/associations/many_to_one.rb
27
- lib/dm-core/associations/one_to_many.rb
28
- lib/dm-core/associations/one_to_one.rb
29
- lib/dm-core/associations/relationship.rb
30
- lib/dm-core/collection.rb
31
- lib/dm-core/core_ext/kernel.rb
32
- lib/dm-core/core_ext/symbol.rb
33
- lib/dm-core/identity_map.rb
34
- lib/dm-core/migrations.rb
35
- lib/dm-core/model.rb
36
- lib/dm-core/model/descendant_set.rb
37
- lib/dm-core/model/hook.rb
38
- lib/dm-core/model/is.rb
39
- lib/dm-core/model/property.rb
40
- lib/dm-core/model/relationship.rb
41
- lib/dm-core/model/scope.rb
42
- lib/dm-core/property.rb
43
- lib/dm-core/property_set.rb
44
- lib/dm-core/query.rb
45
- lib/dm-core/query/conditions/comparison.rb
46
- lib/dm-core/query/conditions/operation.rb
47
- lib/dm-core/query/direction.rb
48
- lib/dm-core/query/operator.rb
49
- lib/dm-core/query/path.rb
50
- lib/dm-core/query/sort.rb
51
- lib/dm-core/repository.rb
52
- lib/dm-core/resource.rb
53
- lib/dm-core/spec/adapter_shared_spec.rb
54
- lib/dm-core/spec/data_objects_adapter_shared_spec.rb
55
- lib/dm-core/support/chainable.rb
56
- lib/dm-core/support/deprecate.rb
57
- lib/dm-core/support/equalizer.rb
58
- lib/dm-core/support/logger.rb
59
- lib/dm-core/support/naming_conventions.rb
60
- lib/dm-core/transaction.rb
61
- lib/dm-core/type.rb
62
- lib/dm-core/types/boolean.rb
63
- lib/dm-core/types/discriminator.rb
64
- lib/dm-core/types/object.rb
65
- lib/dm-core/types/paranoid_boolean.rb
66
- lib/dm-core/types/paranoid_datetime.rb
67
- lib/dm-core/types/serial.rb
68
- lib/dm-core/types/text.rb
69
- lib/dm-core/version.rb
70
- script/performance.rb
71
- script/profile.rb
72
- spec/lib/adapter_helpers.rb
73
- spec/lib/collection_helpers.rb
74
- spec/lib/counter_adapter.rb
75
- spec/lib/pending_helpers.rb
76
- spec/lib/rspec_immediate_feedback_formatter.rb
77
- spec/public/associations/many_to_many_spec.rb
78
- spec/public/associations/many_to_one_spec.rb
79
- spec/public/associations/one_to_many_spec.rb
80
- spec/public/associations/one_to_one_spec.rb
81
- spec/public/collection_spec.rb
82
- spec/public/migrations_spec.rb
83
- spec/public/model/relationship_spec.rb
84
- spec/public/model_spec.rb
85
- spec/public/property_spec.rb
86
- spec/public/resource_spec.rb
87
- spec/public/sel_spec.rb
88
- spec/public/setup_spec.rb
89
- spec/public/shared/association_collection_shared_spec.rb
90
- spec/public/shared/collection_shared_spec.rb
91
- spec/public/shared/finder_shared_spec.rb
92
- spec/public/shared/resource_shared_spec.rb
93
- spec/public/shared/sel_shared_spec.rb
94
- spec/public/transaction_spec.rb
95
- spec/public/types/discriminator_spec.rb
96
- spec/semipublic/adapters/abstract_adapter_spec.rb
97
- spec/semipublic/adapters/in_memory_adapter_spec.rb
98
- spec/semipublic/adapters/mysql_adapter_spec.rb
99
- spec/semipublic/adapters/oracle_adapter_spec.rb
100
- spec/semipublic/adapters/postgres_adapter_spec.rb
101
- spec/semipublic/adapters/sqlite3_adapter_spec.rb
102
- spec/semipublic/adapters/yaml_adapter_spec.rb
103
- spec/semipublic/associations/many_to_one_spec.rb
104
- spec/semipublic/associations/relationship_spec.rb
105
- spec/semipublic/associations_spec.rb
106
- spec/semipublic/collection_spec.rb
107
- spec/semipublic/property_spec.rb
108
- spec/semipublic/query/conditions_spec.rb
109
- spec/semipublic/query/path_spec.rb
110
- spec/semipublic/query_spec.rb
111
- spec/semipublic/resource_spec.rb
112
- spec/semipublic/shared/condition_shared_spec.rb
113
- spec/semipublic/shared/resource_shared_spec.rb
114
- spec/spec.opts
115
- spec/spec_helper.rb
116
- tasks/ci.rb
117
- tasks/dm.rb
118
- tasks/doc.rb
119
- tasks/gemspec.rb
120
- tasks/hoe.rb
121
- tasks/install.rb
data/QUICKLINKS DELETED
@@ -1,11 +0,0 @@
1
- = Quick Links
2
-
3
- * Setup and Configuration - DataMapper
4
- * Finders and CRUD -
5
- * Properties - DataMapper::Property
6
- * FAQ[link:/files/FAQ.html]
7
- * Contact Us
8
- * Website - http://www.datamapper.org
9
- * Bug Reports - http://datamapper.lighthouseapp.com
10
- * IRC Channel - <tt>##datamapper</tt> on irc.freenode.net
11
- * Mailing List - http://groups.google.com/group/datamapper/
data/SPECS DELETED
@@ -1,35 +0,0 @@
1
- Reading Specs
2
- =============
3
-
4
- Blah blah blah...
5
-
6
- Writing Specs
7
- =============
8
-
9
- Here are some general dos and don'ts
10
-
11
- = DO:
12
-
13
- * Write more specs for error conditions than clean conditions.
14
- * Write specs with readability in mind. Somebody new to DataMapper should be
15
- able to read specs to learn how something works.
16
- * Use existing models that are part of a metaphor.
17
- * Nest describe blocks (2 or 3 levels deep is probably fine).
18
- * Limit a describe block to 10 - 15 examples.
19
- * Group specs by method being tested. (See the 'Ordering Specs' section)
20
- * Use custom matchers.
21
-
22
- = DON'T:
23
-
24
- * Spec more than one unit of functionality in an example. An example should be
25
- as short as possible (while still remaining readable).
26
- * Spec implementation. Refactoring code should not break specs.
27
- * Declare models in the spec file.
28
-
29
- And a final do: Do go against the guidelines if your best judgement tells you
30
- to. These are just guidelines and are obviously not fast rules.
31
-
32
- Mocks and Stubs
33
- ===============
34
-
35
- Do not use mocks or stubs for any specs in DataMapper.
data/TODO DELETED
@@ -1 +0,0 @@
1
- See: http://wiki.github.com/datamapper/dm-core
@@ -1,528 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
-
3
- include DataMapper::Query::Conditions
4
-
5
- module ComparisonSpecHelpers
6
-
7
- def match(record)
8
- ComparisonMatcher.new(record)
9
- end
10
-
11
- class ComparisonMatcher
12
-
13
- def initialize(record)
14
- @record = record
15
- end
16
-
17
- def matches?(comparison)
18
- @comparison = comparison
19
- comparison.matches?(@record)
20
- end
21
-
22
- def failure_message
23
- "Expected #{@comparison.inspect} to match #{@record.inspect}"
24
- end
25
-
26
- def negative_failure_message
27
- "Expected #{@comparison.inspect} to NOT match #{@record.inspect}"
28
- end
29
-
30
- end
31
-
32
- end
33
-
34
- describe DataMapper::Query::Conditions do
35
-
36
- include ComparisonSpecHelpers
37
-
38
- before :all do
39
- class ::Mass < DataMapper::Type
40
- primitive Integer
41
-
42
- def self.load(value, property)
43
- { 1 => 'Small', 2 => 'Large', 3 => 'XLarge' }[value]
44
- end
45
-
46
- def self.dump(value, property)
47
- { 'Small' => 1, 'Large' => 2, 'XLarge' => 3 }[value]
48
- end
49
- end
50
-
51
- class ::Heffalump
52
- include DataMapper::Resource
53
-
54
- property :id, Serial
55
- property :color, String
56
- property :num_spots, Integer
57
- property :striped, Boolean
58
- property :mass, Mass, :default => 'Large', :nullable => false
59
-
60
- belongs_to :parent, Heffalump
61
-
62
- # Heffalumps are surprisingly picky when it comes to choosing friends --
63
- # they greatly prefer the company of similarly sized beasts. :)
64
- has n, :mass_mates, Heffalump, :child_key => [:mass], :parent_key => [:mass]
65
- end
66
-
67
- @heff1 = Heffalump.new(:id => 1, :num_spots => 1, :color => 'green', :striped => true, :mass => 'Small')
68
- @heff2 = Heffalump.new(:id => 2, :num_spots => 2, :color => 'green', :striped => false, :mass => 'Large', :parent => @heff1)
69
- @heff3 = Heffalump.new(:id => 3, :num_spots => 3, :color => 'blue', :striped => false, :mass => 'XLarge', :parent => @heff2)
70
- end
71
-
72
- describe 'Operations' do
73
- before do
74
- @comp1 = Comparison.new(:eql, Heffalump.num_spots, 1)
75
- @comp2 = Comparison.new(:eql, Heffalump.color, 'green')
76
- end
77
-
78
- it 'should initialize an AbstractOperation object' do
79
- op = Operation.new(:and)
80
- op.should be_kind_of(AbstractOperation)
81
- end
82
-
83
- {
84
- :and => AndOperation,
85
- :or => OrOperation,
86
- :not => NotOperation
87
- }.each do |operand, klass|
88
- it "should initialize as #{klass} for the #{operand} operator" do
89
- op = Operation.new(operand)
90
- op.should be_kind_of(klass)
91
- end
92
- end
93
-
94
- it 'should set the remaining args in @operands' do
95
- op = Operation.new(:and, @comp1, @comp2)
96
- op.operands.should == [@comp1, @comp2]
97
- end
98
-
99
- it 'should have operands be empty of no operands are provided' do
100
- op = Operation.new(:and)
101
- op.operands.should == []
102
- end
103
-
104
- describe 'NotOperation' do
105
- before do
106
- @op = Operation.new(:not, @comp1)
107
- end
108
-
109
- it 'should not allow more than one operand' do
110
- lambda {
111
- Operation.new(:not, @comp1, @comp2)
112
- }.should raise_error(InvalidOperation)
113
- end
114
-
115
- it 'should negate the comparison' do
116
- @comp1.should match(@heff1)
117
- @op.should_not match(@heff1)
118
- end
119
- end
120
-
121
- describe 'AndOperation' do
122
- before do
123
- @op = Operation.new(:and, @comp1, @comp2)
124
- end
125
-
126
- it 'should match if all comparisons match' do
127
- @comp1.should match(@heff1)
128
- @comp2.should match(@heff1)
129
-
130
- @op.should match(@heff1)
131
- end
132
-
133
- it 'should not match of any of the comparisons does not match' do
134
- @comp1.should_not match(@heff2)
135
-
136
- @op.should_not match(@heff2)
137
- end
138
- end
139
-
140
- describe 'OrOperation' do
141
- before do
142
- @op = Operation.new(:or, @comp1, @comp2)
143
- end
144
-
145
- it 'should match if any of the comparisons match' do
146
- @comp1.should_not match(@heff2)
147
- @comp2.should match(@heff2)
148
-
149
- @op.should match(@heff2)
150
- end
151
-
152
- it 'should not match if none of the comparisons match' do
153
- @comp1.should_not match(@heff3)
154
- @comp2.should_not match(@heff3)
155
-
156
- @op.should_not match(@heff3)
157
- end
158
- end
159
- end
160
-
161
- describe 'Comparisons' do
162
- it 'should initialize an AbstractComparison object' do
163
- comp = Comparison.new(:eql, Heffalump.num_spots, 1)
164
- comp.should be_kind_of(AbstractComparison)
165
- end
166
-
167
- {
168
- :eql => EqualToComparison,
169
- :gt => GreaterThanComparison,
170
- :gte => GreaterThanOrEqualToComparison,
171
- :lt => LessThanComparison,
172
- :lte => LessThanOrEqualToComparison,
173
- :regexp => RegexpComparison
174
- }.each do |slug, klass|
175
- it "should initialize as #{klass} for the #{slug} comparator" do
176
- comp = Comparison.new(slug, Heffalump.num_spots, 2)
177
- comp.should be_kind_of(klass)
178
- end
179
- end
180
-
181
- it 'should initialize as InclusionComparison for the :in comparator' do
182
- comp = Comparison.new(:in, Heffalump.num_spots, [ 2 ])
183
- comp.should be_kind_of(InclusionComparison)
184
- end
185
-
186
- describe 'EqualToComparison' do
187
- describe 'with a value matching the property primitive' do
188
- before :all do
189
- @comp = Comparison.new(:eql, Heffalump.striped, false)
190
- end
191
-
192
- it_should_behave_like 'A valid query condition'
193
-
194
- it 'should match records that equal the given value' do
195
- @comp.should match(@heff2)
196
- @comp.should match(@heff3)
197
- end
198
-
199
- it 'should not match records that do not equal the given value' do
200
- @comp.should_not match(@heff1)
201
- end
202
- end
203
-
204
- describe 'with a value coerced into the property primitive' do
205
- before :all do
206
- @comp = Comparison.new(:eql, Heffalump.striped, 'false')
207
- end
208
-
209
- it_should_behave_like 'A valid query condition'
210
-
211
- it 'should match records that equal the given value' do
212
- @comp.should match(@heff2)
213
- @comp.should match(@heff3)
214
- end
215
-
216
- it 'should not match records that do not equal the given value' do
217
- @comp.should_not match(@heff1)
218
- end
219
- end
220
-
221
- describe 'with a value from a custom type' do
222
- before :all do
223
- @comp = Comparison.new(:eql, Heffalump.mass, 'Large')
224
- end
225
-
226
- it_should_behave_like 'A valid query condition'
227
-
228
- it 'should match records that equal the given value' do
229
- @comp.should match(@heff2)
230
- end
231
-
232
- it 'should not match records that do not equal the given value' do
233
- @comp.should_not match(@heff1)
234
- @comp.should_not match(@heff3)
235
- end
236
- end
237
-
238
- describe 'with a relationship subject' do
239
- before :all do
240
- @comp = Comparison.new(:eql, Heffalump.relationships[:parent], @heff1)
241
- end
242
-
243
- it_should_behave_like 'A valid query condition'
244
-
245
- it 'should match records that equal the given value' do
246
- @comp.should match(@heff2)
247
- end
248
-
249
- it 'should not match records that do not equal the given value' do
250
- @comp.should_not match(@heff1)
251
- @comp.should_not match(@heff3)
252
- end
253
- end
254
-
255
- describe 'with a relationship subject using a custom type key' do
256
- before :all do
257
- @comp = Comparison.new(:eql, Heffalump.relationships[:mass_mates], @heff1)
258
- end
259
-
260
- it_should_behave_like 'A valid query condition'
261
-
262
- it 'should match records that equal the given value' do
263
- @comp.should match(Heffalump.new(:id => 4, :mass => 'Small'))
264
- @comp.should match(@heff1)
265
- end
266
-
267
- it 'should not match records that do not equal the given value' do
268
- @comp.should_not match(@heff2)
269
- @comp.should_not match(@heff3)
270
- end
271
- end
272
- end
273
-
274
- describe 'InclusionComparison' do
275
- describe 'with a value matching the property primitive' do
276
- before :all do
277
- @comp = Comparison.new(:in, Heffalump.num_spots, 1..2)
278
- end
279
-
280
- it_should_behave_like 'A valid query condition'
281
-
282
- it 'should match records that equal the given value' do
283
- @comp.should match(@heff1)
284
- @comp.should match(@heff2)
285
- end
286
-
287
- it 'should not match records that do not equal the given value' do
288
- @comp.should_not match(@heff3)
289
- end
290
- end
291
-
292
- describe 'with a value coerced into the property primitive' do
293
- before :all do
294
- @comp = Comparison.new(:in, Heffalump.num_spots, '1'..'2')
295
- end
296
-
297
- it_should_behave_like 'A valid query condition'
298
-
299
- it 'should match records that equal the given value' do
300
- @comp.should match(@heff1)
301
- @comp.should match(@heff2)
302
- end
303
-
304
- it 'should not match records that do not equal the given value' do
305
- @comp.should_not match(@heff3)
306
- end
307
- end
308
-
309
- describe 'with a value from a custom type' do
310
- before :all do
311
- @comp = Comparison.new(:in, Heffalump.mass, ['Small', 'Large'])
312
- end
313
-
314
- it_should_behave_like 'A valid query condition'
315
-
316
- it 'should match records that equal the given value' do
317
- @comp.should match(@heff1)
318
- @comp.should match(@heff2)
319
- end
320
-
321
- it 'should not match records that do not equal the given value' do
322
- @comp.should_not match(@heff3)
323
- end
324
- end
325
-
326
- describe 'with a relationship subject' do
327
- before :all do
328
- @comp = Comparison.new(:in, Heffalump.relationships[:parent], [@heff1, @heff2])
329
- end
330
-
331
- it_should_behave_like 'A valid query condition'
332
-
333
- it 'should match records that equal the given value' do
334
- @comp.should match(@heff2)
335
- @comp.should match(@heff3)
336
- end
337
-
338
- it 'should not match records that do not equal the given value' do
339
- @comp.should_not match(@heff1)
340
- end
341
- end
342
-
343
- describe 'with a relationship subject using a custom type key' do
344
- before :all do
345
- @comp = Comparison.new(:in, Heffalump.relationships[:mass_mates], [@heff1, @heff2])
346
- end
347
-
348
- it_should_behave_like 'A valid query condition'
349
-
350
- it 'should match records that equal the given value' do
351
- @comp.should match(Heffalump.new(:mass => 'Small'))
352
- @comp.should match(Heffalump.new(:mass => 'Large'))
353
- @comp.should match(@heff1)
354
- @comp.should match(@heff2)
355
- end
356
-
357
- it 'should not match records that do not equal the given value' do
358
- @comp.should_not match(@heff3)
359
- end
360
- end
361
- end
362
-
363
- describe 'GreaterThanComparison' do
364
- describe 'with a value matching the property primitive' do
365
- before :all do
366
- @comp = Comparison.new(:gt, Heffalump.num_spots, 2)
367
- end
368
-
369
- it_should_behave_like 'A valid query condition'
370
-
371
- it 'should match records that are greater than the given value' do
372
- @comp.should match(@heff3)
373
- end
374
-
375
- it 'should not match records that are not greater than the given value' do
376
- @comp.should_not match(@heff1)
377
- @comp.should_not match(@heff2)
378
- end
379
- end
380
-
381
- describe 'with a value coerced into the property primitive' do
382
- before :all do
383
- @comp = Comparison.new(:gt, Heffalump.num_spots, '2')
384
- end
385
-
386
- it_should_behave_like 'A valid query condition'
387
-
388
- it 'should match records that are greater than the given value' do
389
- @comp.should match(@heff3)
390
- end
391
-
392
- it 'should not match records that are not greater than the given value' do
393
- @comp.should_not match(@heff1)
394
- @comp.should_not match(@heff2)
395
- end
396
- end
397
- end
398
-
399
- describe 'GreaterThanOrEqualToComparison' do
400
- describe 'with a value matching the property primitive' do
401
- before :all do
402
- @comp = Comparison.new(:gte, Heffalump.num_spots, 2)
403
- end
404
-
405
- it_should_behave_like 'A valid query condition'
406
-
407
- it 'should match records that are greater than or equal to the given value' do
408
- @comp.should match(@heff2)
409
- @comp.should match(@heff3)
410
- end
411
-
412
- it 'should not match records that are not greater than or equal to the given value' do
413
- @comp.should_not match(@heff1)
414
- end
415
- end
416
-
417
- describe 'with a value coerced into the property primitive' do
418
- before :all do
419
- @comp = Comparison.new(:gte, Heffalump.num_spots, 2.0)
420
- end
421
-
422
- it_should_behave_like 'A valid query condition'
423
-
424
- it 'should match records that are greater than or equal to the given value' do
425
- @comp.should match(@heff2)
426
- @comp.should match(@heff3)
427
- end
428
-
429
- it 'should not match records that are not greater than or equal to the given value' do
430
- @comp.should_not match(@heff1)
431
- end
432
- end
433
- end
434
-
435
- describe 'LessThanComparison' do
436
- describe 'with a value matching the property primitive' do
437
- before :all do
438
- @comp = Comparison.new(:lt, Heffalump.num_spots, 2)
439
- end
440
-
441
- it_should_behave_like 'A valid query condition'
442
-
443
- it 'should match records that are less than the given value' do
444
- @comp.should match(@heff1)
445
- end
446
-
447
- it 'should not match records that are not less than the given value' do
448
- @comp.should_not match(@heff2)
449
- @comp.should_not match(@heff3)
450
- end
451
- end
452
-
453
- describe 'with a value coerced into the property primitive' do
454
- before :all do
455
- @comp = Comparison.new(:lt, Heffalump.num_spots, BigDecimal('2.0'))
456
- end
457
-
458
- it_should_behave_like 'A valid query condition'
459
-
460
- it 'should match records that are less than the given value' do
461
- @comp.should match(@heff1)
462
- end
463
-
464
- it 'should not match records that are not less than the given value' do
465
- @comp.should_not match(@heff2)
466
- @comp.should_not match(@heff3)
467
- end
468
- end
469
- end
470
-
471
- describe 'LessThanOrEqualToComparison' do
472
- describe 'with a value matching the property primitive' do
473
- before :all do
474
- @comp = Comparison.new(:lte, Heffalump.num_spots, 2)
475
- end
476
-
477
- it_should_behave_like 'A valid query condition'
478
-
479
- it 'should match records that are less than or equal to the given value' do
480
- @comp.should match(@heff1)
481
- @comp.should match(@heff2)
482
- end
483
-
484
- it 'should not match records that are not less than or equal to the given value' do
485
- @comp.should_not match(@heff3)
486
- end
487
- end
488
-
489
- describe 'with a value coerced into the property primitive' do
490
- before :all do
491
- @comp = Comparison.new(:lte, Heffalump.num_spots, '2')
492
- end
493
-
494
- it_should_behave_like 'A valid query condition'
495
-
496
- it 'should match records that are less than or equal to the given value' do
497
- @comp.should match(@heff1)
498
- @comp.should match(@heff2)
499
- end
500
-
501
- it 'should not match records that are not less than or equal to the given value' do
502
- @comp.should_not match(@heff3)
503
- end
504
- end
505
- end
506
-
507
- describe 'RegexpComparison' do
508
- before :all do
509
- @comp = Comparison.new(:regexp, Heffalump.color, /green/)
510
- @heff2.color = 'forest green'
511
- end
512
-
513
- it_should_behave_like 'A valid query condition'
514
-
515
- it 'should match records that match the regexp' do
516
- @comp.should match(@heff1)
517
- @comp.should match(@heff2)
518
- end
519
-
520
- it "should not match records that don't match the regexp" do
521
- @comp.should_not match(@heff3)
522
- end
523
-
524
- end
525
-
526
- end
527
-
528
- end