passiverecord 0.0.1

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.
@@ -0,0 +1,6 @@
1
+ == 0.0.1 2007-09-26
2
+
3
+ * Initial release
4
+ * proof of concept
5
+ * create, find, find_by_*
6
+ * has_many, has_one
@@ -0,0 +1,12 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/passive_record.rb
6
+ lib/passive_record/associations.rb
7
+ lib/passive_record/base.rb
8
+ lib/passive_record/schema.rb
9
+ lib/passive_record/version.rb
10
+ test/test_associations.rb
11
+ test/test_base.rb
12
+ test/test_helper.rb
@@ -0,0 +1,79 @@
1
+ = PassiveRecord
2
+ by Jason L Perry (http://paint.itred.org)
3
+
4
+ == DESCRIPTION:
5
+
6
+ A replacement for ActiveRecord when you just need to model
7
+ a few unchanging objects, and don't necessarily need a full blown
8
+ ActiveRecord class and table in the database.
9
+
10
+ == FEATURES:
11
+
12
+ * some basic ActiveRecord style finders
13
+ * dynamic attribute based finders, supporting basic comparisons as well
14
+ regular expressions and ranges
15
+ * some integrated ActiveRecord associactions, ie: ActiveRecord#belongs_to(:passive_record)
16
+ PassiveRecord#has_many(:active_records) (excluding has_many :through)
17
+
18
+ == TODOs:
19
+
20
+ * has_many :through
21
+ * extend find options like :conditions, :order
22
+ * find(:first) (depends on :order being implemented)
23
+ * better documentation of the code
24
+ * fix warnings in tests
25
+
26
+ == SYNOPSIS:
27
+
28
+ class Continent < PassiveRecord::Base
29
+ has_many :countries # => an ActiveRecord class
30
+
31
+ schema :name => String, :size => Integer, :population => Integer
32
+
33
+ create :name => "Africa", :size => 30370000, :population => 890000000
34
+ create :name => "Antarctica", :size => 13720000, :population => 1000
35
+ create :name => "Australia", :size => 7600000, :population => 20000000
36
+ create :name => "Eurasia", :size => 53990000, :population => 4510000000
37
+ create :name => "North America", :size => 24490000, :population => 515000000
38
+ create :name => "South America", :size => 17840000, :population => 371000000
39
+ end
40
+
41
+ Continent.find(1) # => Africa
42
+ Continent.find_by_name("Africa") # => Yes, also Africa
43
+ Continent.find_by_name_and_size(/America/, 17840000) # => South America
44
+ Continent.find_all_by_population(1000..20000000) # => Antarctica and Australia
45
+ Continent.find(:all) # => All 6 (though not in any particular order, yet)
46
+
47
+ == REQUIREMENTS:
48
+
49
+ * activerecord
50
+
51
+ == INSTALL:
52
+
53
+ * gem install passiverecord
54
+ * require "passive_record"
55
+
56
+ == LICENSE:
57
+
58
+ (The MIT License)
59
+
60
+ Copyright (c) 2007 Jason L Perry (Paint.itRed)
61
+
62
+ Permission is hereby granted, free of charge, to any person obtaining
63
+ a copy of this software and associated documentation files (the
64
+ 'Software'), to deal in the Software without restriction, including
65
+ without limitation the rights to use, copy, modify, merge, publish,
66
+ distribute, sublicense, and/or sell copies of the Software, and to
67
+ permit persons to whom the Software is furnished to do so, subject to
68
+ the following conditions:
69
+
70
+ The above copyright notice and this permission notice shall be
71
+ included in all copies or substantial portions of the Software.
72
+
73
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
74
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
75
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
76
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
77
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
78
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
79
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ $:.unshift(File.dirname(__FILE__) + "/lib")
2
+ require 'rubygems'
3
+ require 'hoe'
4
+
5
+ require 'passive_record/version'
6
+
7
+ Hoe.new('passiverecord', PassiveRecord::VERSION::STRING) do |p|
8
+ p.rubyforge_name = 'paintitred'
9
+ p.author = 'Jason L Perry'
10
+ p.email = 'jasper@ambethia.com'
11
+ p.summary = 'Pacifying overactive records'
12
+ p.description = 'Pacifying overactive records'
13
+ p.url = "http://code.itred.org/projects/passive-record"
14
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
+ p.extra_deps = [['activerecord', '>= 1.15.3']]
16
+ p.remote_rdoc_dir = "passive_record"
17
+ end
18
+
19
+ Hoe.send :define_method, :extra_deps, proc { @extra_deps.reject! { |x| Array(x).first == 'hoe' };@extra_deps}
@@ -0,0 +1,17 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ begin
4
+ require 'active_record'
5
+ rescue LoadError => e
6
+ require 'rubygems'
7
+ require 'active_record'
8
+ end
9
+
10
+ require 'passive_record/base'
11
+ require 'passive_record/schema'
12
+ require 'passive_record/associations'
13
+
14
+ PassiveRecord::Base.class_eval do
15
+ include PassiveRecord::Schema
16
+ include PassiveRecord::Associations
17
+ end
@@ -0,0 +1,276 @@
1
+ # Currently this is a big hack job of code from active record
2
+ # TODO: Trim this down, and test it thoroughly
3
+ module PassiveRecord
4
+ module Associations
5
+
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+
9
+ ActiveRecord::Callbacks::CALLBACKS.each do |method|
10
+ base.class_eval <<-"end_eval"
11
+ def self.#{method}(*callbacks, &block)
12
+ callbacks << block if block_given?
13
+ write_inheritable_array(#{method.to_sym.inspect}, callbacks)
14
+ end
15
+ end_eval
16
+ end
17
+ end
18
+
19
+ def quoted_id #:nodoc:
20
+ ActiveRecord::Base.quote_value(self.key)
21
+ end
22
+
23
+ def attribute_present?(attribute)
24
+ value = self.respond_to?(attribute) ? self.send(attribute) : nil
25
+ !value.blank? or value == 0
26
+ end
27
+
28
+ def read_attribute(attribute)
29
+ self.send(attribute)
30
+ end
31
+
32
+ def new_record?
33
+ false
34
+ end
35
+
36
+ module ClassMethods
37
+
38
+ def has_many(association_id, options = {}, &extension)
39
+ reflection = create_has_many_reflection(association_id, options, &extension)
40
+
41
+ ActiveRecord::Base.send(:configure_dependency_for_has_many, reflection)
42
+
43
+ if options[:through]
44
+ collection_reader_method(reflection, ActiveRecord::Associations::HasManyThroughAssociation)
45
+ else
46
+ add_multiple_associated_save_callbacks(reflection.name)
47
+ add_association_callbacks(reflection.name, reflection.options)
48
+ collection_accessor_methods(reflection, ActiveRecord::Associations::HasManyAssociation)
49
+ end
50
+ end
51
+
52
+ def has_one(association_id, options = {})
53
+ reflection = create_has_one_reflection(association_id, options)
54
+
55
+ module_eval do
56
+ after_save <<-EOF
57
+ association = instance_variable_get("@#{reflection.name}")
58
+ if !association.nil? && (new_record? || association.new_record? || association["#{reflection.primary_key_name}"] != id)
59
+ association["#{reflection.primary_key_name}"] = id
60
+ association.save(true)
61
+ end
62
+ EOF
63
+ end
64
+
65
+ association_accessor_methods(reflection, ActiveRecord::Associations::HasOneAssociation)
66
+ association_constructor_method(:build, reflection, ActiveRecord::Associations::HasOneAssociation)
67
+ association_constructor_method(:create, reflection, ActiveRecord::Associations::HasOneAssociation)
68
+
69
+ ActiveRecord::Base.send(:configure_dependency_for_has_one, reflection)
70
+ end
71
+
72
+ def create_has_many_reflection(association_id, options, &extension)
73
+ options.assert_valid_keys(
74
+ :class_name, :table_name, :foreign_key,
75
+ :exclusively_dependent, :dependent,
76
+ :select, :conditions, :include, :order, :group, :limit, :offset,
77
+ :as, :through, :source, :source_type,
78
+ :uniq,
79
+ :finder_sql, :counter_sql,
80
+ :before_add, :after_add, :before_remove, :after_remove,
81
+ :extend
82
+ )
83
+
84
+ options[:extend] = create_extension_module(association_id, extension) if block_given?
85
+
86
+ create_reflection(:has_many, association_id, options, self)
87
+ end
88
+
89
+ def create_has_one_reflection(association_id, options)
90
+ options.assert_valid_keys(
91
+ :class_name, :foreign_key, :remote, :conditions, :order, :include, :dependent, :counter_cache, :extend, :as
92
+ )
93
+
94
+ create_reflection(:has_one, association_id, options, self)
95
+ end
96
+
97
+ def create_reflection(macro, name, options, active_record)
98
+ case macro
99
+ when :has_many, :belongs_to, :has_one, :has_and_belongs_to_many
100
+ reflection = ActiveRecord::Reflection::AssociationReflection.new(macro, name, options, active_record)
101
+ when :composed_of
102
+ reflection = AggregateReflection.new(macro, name, options, active_record)
103
+ end
104
+ write_inheritable_hash :reflections, name => reflection
105
+ reflection
106
+ end
107
+
108
+ def add_multiple_associated_save_callbacks(association_name)
109
+ method_name = "validate_associated_records_for_#{association_name}".to_sym
110
+ define_method(method_name) do
111
+ association = instance_variable_get("@#{association_name}")
112
+ if association.respond_to?(:loaded?)
113
+ if new_record?
114
+ association
115
+ else
116
+ association.select { |record| record.new_record? }
117
+ end.each do |record|
118
+ errors.add "#{association_name}" unless record.valid?
119
+ end
120
+ end
121
+ end
122
+
123
+ validate method_name
124
+ before_save("@new_record_before_save = new_record?; true")
125
+
126
+ after_callback = <<-end_eval
127
+ association = instance_variable_get("@#{association_name}")
128
+
129
+ if association.respond_to?(:loaded?)
130
+ if @new_record_before_save
131
+ records_to_save = association
132
+ else
133
+ records_to_save = association.select { |record| record.new_record? }
134
+ end
135
+ records_to_save.each { |record| association.send(:insert_record, record) }
136
+ association.send(:construct_sql) # reconstruct the SQL queries now that we know the owner's id
137
+ end
138
+ end_eval
139
+
140
+ # Doesn't use after_save as that would save associations added in after_create/after_update twice
141
+ after_create(after_callback)
142
+ after_update(after_callback)
143
+ end
144
+
145
+ def add_association_callbacks(association_name, options)
146
+ callbacks = %w(before_add after_add before_remove after_remove)
147
+ callbacks.each do |callback_name|
148
+ full_callback_name = "#{callback_name}_for_#{association_name}"
149
+ defined_callbacks = options[callback_name.to_sym]
150
+ if options.has_key?(callback_name.to_sym)
151
+ class_inheritable_reader full_callback_name.to_sym
152
+ write_inheritable_array(full_callback_name.to_sym, [defined_callbacks].flatten)
153
+ end
154
+ end
155
+ end
156
+
157
+ def collection_accessor_methods(reflection, association_proxy_class)
158
+ collection_reader_method(reflection, association_proxy_class)
159
+
160
+ define_method("#{reflection.name}=") do |new_value|
161
+ # Loads proxy class instance (defined in collection_reader_method) if not already loaded
162
+ association = send(reflection.name)
163
+ association.replace(new_value)
164
+ association
165
+ end
166
+
167
+ define_method("#{reflection.name.to_s.singularize}_ids") do
168
+ send(reflection.name).map(&:id)
169
+ end
170
+
171
+ define_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
172
+ ids = (new_value || []).reject { |nid| nid.blank? }
173
+ send("#{reflection.name}=", reflection.class_name.constantize.find(ids))
174
+ end
175
+ end
176
+
177
+ def collection_reader_method(reflection, association_proxy_class)
178
+ define_method(reflection.name) do |*params|
179
+ force_reload = params.first unless params.empty?
180
+ association = instance_variable_get("@#{reflection.name}")
181
+
182
+ unless association.respond_to?(:loaded?)
183
+ association = association_proxy_class.new(self, reflection)
184
+ instance_variable_set("@#{reflection.name}", association)
185
+ end
186
+
187
+ association.reload if force_reload
188
+
189
+ association
190
+ end
191
+ end
192
+
193
+ def association_accessor_methods(reflection, association_proxy_class)
194
+ define_method(reflection.name) do |*params|
195
+ force_reload = params.first unless params.empty?
196
+ association = instance_variable_get("@#{reflection.name}")
197
+
198
+ if association.nil? || force_reload
199
+ association = association_proxy_class.new(self, reflection)
200
+ retval = association.reload
201
+ if retval.nil? and association_proxy_class == BelongsToAssociation
202
+ instance_variable_set("@#{reflection.name}", nil)
203
+ return nil
204
+ end
205
+ instance_variable_set("@#{reflection.name}", association)
206
+ end
207
+
208
+ association.target.nil? ? nil : association
209
+ end
210
+
211
+ define_method("#{reflection.name}=") do |new_value|
212
+ association = instance_variable_get("@#{reflection.name}")
213
+ if association.nil?
214
+ association = association_proxy_class.new(self, reflection)
215
+ end
216
+
217
+ association.replace(new_value)
218
+
219
+ unless new_value.nil?
220
+ instance_variable_set("@#{reflection.name}", association)
221
+ else
222
+ instance_variable_set("@#{reflection.name}", nil)
223
+ return nil
224
+ end
225
+
226
+ association
227
+ end
228
+
229
+ define_method("set_#{reflection.name}_target") do |target|
230
+ return if target.nil? and association_proxy_class == BelongsToAssociation
231
+ association = association_proxy_class.new(self, reflection)
232
+ association.target = target
233
+ instance_variable_set("@#{reflection.name}", association)
234
+ end
235
+ end
236
+
237
+ def association_constructor_method(constructor, reflection, association_proxy_class)
238
+ define_method("#{constructor}_#{reflection.name}") do |*params|
239
+ attributees = params.first unless params.empty?
240
+ replace_existing = params[1].nil? ? true : params[1]
241
+ association = instance_variable_get("@#{reflection.name}")
242
+
243
+ if association.nil?
244
+ association = association_proxy_class.new(self, reflection)
245
+ instance_variable_set("@#{reflection.name}", association)
246
+ end
247
+
248
+ if association_proxy_class == HasOneAssociation
249
+ association.send(constructor, attributees, replace_existing)
250
+ else
251
+ association.send(constructor, attributees)
252
+ end
253
+ end
254
+ end
255
+
256
+ def validate(*methods, &block)
257
+ methods << block if block_given?
258
+ write_inheritable_set(:validate, methods)
259
+ end
260
+
261
+ def write_inheritable_set(key, methods)
262
+ existing_methods = read_inheritable_attribute(key) || []
263
+ write_inheritable_attribute(key, methods | existing_methods)
264
+ end
265
+
266
+ def compute_type(*args)
267
+ ActiveRecord::Base.send(:compute_type, *args)
268
+ end
269
+
270
+ def reflect_on_association(*args)
271
+ ActiveRecord::Base.send(:reflect_on_association, *args)
272
+ end
273
+
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,126 @@
1
+ module PassiveRecord
2
+ class PassiveRecordError < StandardError; end
3
+ class RecordNotFound < PassiveRecordError; end
4
+
5
+ class Base
6
+ @@instances = {}
7
+
8
+ attr_accessor :attributes, :key
9
+
10
+ alias :id :key
11
+
12
+ def initialize(attributes = {})
13
+ @attributes = attributes
14
+ yield self if block_given?
15
+ end
16
+
17
+ def [](attribute_name)
18
+ self.attributes[attribute_name]
19
+ end
20
+
21
+ def []=(attribute_name, value)
22
+ self.attributes[attribute_name] = value
23
+ end
24
+
25
+ def ==(comparison_object)
26
+ comparison_object.equal?(self) ||
27
+ (comparison_object.instance_of?(self.class) &&
28
+ comparison_object.id == id &&
29
+ !comparison_object.new_record?)
30
+ end
31
+
32
+
33
+ class << self
34
+
35
+ def create(*args)
36
+ attributes = extract_options!(args)
37
+ key = args.first || @@instances.size+1
38
+ instance = self.new(attributes)
39
+ instance.key = key
40
+ @@instances[key] = instance
41
+ return key
42
+ end
43
+
44
+ private :create
45
+
46
+ def find(*args)
47
+ options = extract_options!(args)
48
+ args.first == :all ? find_every : find_from_keys(args)
49
+ end
50
+
51
+ def count
52
+ find_every.size
53
+ end
54
+
55
+ protected
56
+
57
+ # def find_initial(options)
58
+ # end
59
+
60
+ def find_every
61
+ @@instances.select { |key, value| value.is_a?(self) }.map {|its| its.last}
62
+ end
63
+
64
+ def find_from_keys(keys, options = {})
65
+
66
+ expects_array = keys.first.kind_of?(Array)
67
+ return keys.first if expects_array && keys.first.empty?
68
+ keys = keys.flatten.compact.uniq
69
+
70
+ case keys.size
71
+ when 0
72
+ raise RecordNotFound, "Couldn't find #{name} without a key"
73
+ when 1
74
+ result = find_one(keys.first)
75
+ expects_array ? [ result ] : result
76
+ else
77
+ find_some(keys)
78
+ end
79
+ end
80
+
81
+ def find_one(_key)
82
+ values = @@instances.select { |key, value| _key == key && value.is_a?(self) }.map {|its| its.last}
83
+ unless values.empty?
84
+ return values.first
85
+ else
86
+ raise RecordNotFound, "Couldn't find #{name} with the given key."
87
+ end
88
+ end
89
+
90
+ def find_some(keys)
91
+ values = @@instances.select { |key, value| (keys).include?(key) && value.is_a?(self) }.map {|its| its.last}
92
+ end
93
+
94
+ def extract_options!(args) #:nodoc:
95
+ args.last.is_a?(Hash) ? args.pop : {}
96
+ end
97
+
98
+ # TODO: clean this mess up
99
+ def method_missing(method_id, *arguments)
100
+ if match = /^find_(all_by|by)_([_a-zA-Z]\w*)$/.match(method_id.to_s)
101
+ expects_array = match.captures.first == 'all_by'
102
+ attribute_names = match.captures.last.split('_and_')
103
+ # super unless all_attributes_exists?(attribute_names)
104
+ attributes = {}
105
+ attribute_names.each_with_index { |name, idx| attributes[name] = arguments[idx] }
106
+ expressions = []
107
+ attributes.each_pair { |key, value| expressions << attribute_expression("value.#{key}", value) }
108
+ results = @@instances.select { |key, value| eval expressions.join(" && ") }.map {|its| its.last}
109
+ return expects_array ? results : results.pop
110
+ else
111
+ super
112
+ end
113
+ end
114
+
115
+ def attribute_expression(name, argument)
116
+ case argument
117
+ when Regexp then "#{name} =~ /#{argument}/"
118
+ when Range then "(#{argument}).include?(#{name})"
119
+ when String then "#{name} == \"#{argument}\""
120
+ else "#{name} == #{argument}"
121
+ end
122
+ end
123
+
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,25 @@
1
+ module PassiveRecord
2
+ module Schema
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ # Define the schema for your model, this also adds attribute accessors for schema columns
11
+ def schema(definition = {})
12
+ @@schema = definition
13
+ definition.keys.each do |attribute_name|
14
+ define_method("#{attribute_name}") do
15
+ self[attribute_name]
16
+ end
17
+ define_method("#{attribute_name}=") do |new_value|
18
+ self[attribute_name] = new_value
19
+ end
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ module PassiveRecord #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,96 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class Room < PassiveRecord::Base
4
+ has_many :furniture, :order => :name
5
+ has_one :light_fixture, :class_name => "Furniture"
6
+
7
+ has_many :ins, :class_name => "Door", :foreign_key => "outside_id"
8
+ has_many :outs, :class_name => "Door", :foreign_key => "inside_id"
9
+
10
+ has_many :exits, :through => :outs
11
+ has_many :entrances, :through => :ins
12
+
13
+ schema :name => String
14
+
15
+ create :name => "Family Room"
16
+ create :name => "Kitchen"
17
+ create :name => "Bedroom"
18
+ create :name => "Restroom"
19
+ create :name => "Office"
20
+ end
21
+
22
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
23
+ ActiveRecord::Base.connection.create_table "furniture", :force => true do |t|
24
+ t.column :name, :string
25
+ t.column :room_id, :integer
26
+ end
27
+
28
+ ActiveRecord::Base.connection.create_table "doors", :force => true do |t|
29
+ t.column :inside_id, :integer
30
+ t.column :outside_id, :integer
31
+ end
32
+
33
+ Inflector.inflections { |inflect| inflect.uncountable %w( furniture )}
34
+
35
+ class Furniture < ActiveRecord::Base
36
+ belongs_to :room
37
+ end
38
+
39
+ class Door < ActiveRecord::Base
40
+ belongs_to :inside, :class_name => "Room", :foreign_key => "inside_id"
41
+ belongs_to :outside, :class_name => "Room", :foreign_key => "outside_id"
42
+ end
43
+
44
+ class PassiveRecord::AssociationsTest < Test::Unit::TestCase
45
+
46
+ # some "fixtures"
47
+ def setup
48
+ Furniture.create :name => "Couch", :room_id => Room.find_by_name("Family Room").id
49
+ Furniture.create :name => "Ottoman", :room_id => Room.find_by_name("Family Room").id
50
+ Furniture.create :name => "Ott-lite", :room_id => Room.find_by_name("Office").id
51
+
52
+ Door.create :inside_id => Room.find_by_name("Office").id,
53
+ :outside_id => Room.find_by_name("Family Room").id
54
+
55
+ Door.create :inside_id => Room.find_by_name("Restroom").id,
56
+ :outside_id => Room.find_by_name("Family Room").id
57
+ end
58
+
59
+ def test_should_have_many
60
+ furniture = [
61
+ Furniture.find_by_name("Couch"),
62
+ Furniture.find_by_name("Ottoman")
63
+ ]
64
+ room = Room.find_by_name("Family Room")
65
+ assert_equal furniture, room.furniture
66
+ end
67
+
68
+ def test_should_have_many_through
69
+ rooms = [
70
+ Room.find_by_name("Office"),
71
+ Room.find_by_name("Restroom")
72
+ ]
73
+
74
+ room = Room.find_by_name("Family Room")
75
+
76
+ # assert_equal room, room.exits
77
+ end
78
+
79
+ def test_should_have_one
80
+ lamp = Furniture.find_by_name("Ott-lite")
81
+ room = Room.find_by_name("Office")
82
+ assert_equal lamp, room.light_fixture
83
+ end
84
+
85
+ def test_should_belong_to
86
+ lamp = Furniture.find_by_name("Ott-lite")
87
+ room = Room.find_by_name("Office")
88
+
89
+ assert_equal room, lamp.room
90
+ end
91
+
92
+ def teardown
93
+ Furniture.delete_all
94
+ end
95
+
96
+ end
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class Continent < PassiveRecord::Base
4
+ schema :name => String, :size => Integer, :population => Integer
5
+ end
6
+
7
+ class PassiveRecord::BaseTest < Test::Unit::TestCase
8
+
9
+ def setup
10
+ # Add the geographic 6 continents
11
+ Continent.send :create, :name => "Africa", :size => 30370000, :population => 890000000
12
+ Continent.send :create, :name => "Antarctica", :size => 13720000, :population => 1000
13
+ Continent.send :create, :name => "Australia", :size => 7600000, :population => 20000000
14
+ Continent.send :create, :name => "Eurasia", :size => 53990000, :population => 4510000000
15
+ Continent.send :create, :name => "North America", :size => 24490000, :population => 515000000
16
+ Continent.send :create, :name => "South America", :size => 17840000, :population => 371000000
17
+ end
18
+
19
+ def test_should_create_instance
20
+ assert_equal 7, Continent.send(:create, :name => "Atlantis", :size => 0, :population => 0)
21
+ end
22
+
23
+ def test_should_create_instance_with_manual_key
24
+ assert_equal "ATL", Continent.send(:create, "ATL", :name => "Atlantis", :size => 0, :population => 0)
25
+ assert Continent.find("ATL")
26
+ end
27
+
28
+ def test_should_count_instances
29
+ assert_equal 6, Continent.count
30
+ end
31
+
32
+ def test_should_find_one_by_key
33
+ assert Continent.find(1).is_a?(Continent)
34
+ end
35
+
36
+ def test_should_find_one_by_key_as_array
37
+ assert Continent.find([6]).is_a?(Array)
38
+ end
39
+
40
+ def test_should_find_some_by_key
41
+ assert_equal 2, Continent.find(1,2).size
42
+ end
43
+
44
+ def test_should_find_some_by_key_as_array
45
+ assert_equal 2, Continent.find([5,6]).size
46
+ assert_equal 2, Continent.find([5,6,7]).size
47
+ end
48
+
49
+ def test_should_find_all
50
+ assert_equal 6, Continent.find(:all).size
51
+ end
52
+
53
+ def test_should_get_attributes
54
+ assert_equal "Africa", Continent.find(1).name
55
+ assert_equal 1000, Continent.find(2).population
56
+ end
57
+
58
+ def test_should_set_attributes
59
+ assert Continent.find(1).name = "Motherland"
60
+ assert_equal "Motherland", Continent.find(1).name
61
+ end
62
+
63
+ def test_should_find_by_attribute
64
+ assert_equal Continent.find(1), Continent.find_by_name("Africa")
65
+ assert_equal Continent.find(5), Continent.find_by_population(515000000)
66
+ end
67
+
68
+ def test_should_find_all_by_attribute_as_regex
69
+ assert_equal Continent.find(5,6), Continent.find_all_by_name(/America/)
70
+ end
71
+
72
+ def test_should_find_all_by_attribute_in_range
73
+ assert_equal Continent.find(2,3), Continent.find_all_by_population(1000..20000000)
74
+ end
75
+
76
+ def test_should_find_by_many_attributes
77
+ assert_equal Continent.find(6), Continent.find_by_name_and_size(/America/, 17840000)
78
+ end
79
+
80
+ def test_should_puts_some_stuff
81
+ end
82
+
83
+ def teardown
84
+ Continent.send :class_variable_set, "@@instances", {}
85
+ end
86
+
87
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/passive_record'
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: passiverecord
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-09-26 00:00:00 -04:00
8
+ summary: Pacifying overactive records
9
+ require_paths:
10
+ - lib
11
+ email: jasper@ambethia.com
12
+ homepage: http://code.itred.org/projects/passive-record
13
+ rubyforge_project: paintitred
14
+ description: Pacifying overactive records
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Jason L Perry
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - lib/passive_record.rb
37
+ - lib/passive_record/associations.rb
38
+ - lib/passive_record/base.rb
39
+ - lib/passive_record/schema.rb
40
+ - lib/passive_record/version.rb
41
+ - test/test_associations.rb
42
+ - test/test_base.rb
43
+ - test/test_helper.rb
44
+ test_files:
45
+ - test/test_associations.rb
46
+ - test/test_base.rb
47
+ - test/test_helper.rb
48
+ rdoc_options:
49
+ - --main
50
+ - README.txt
51
+ extra_rdoc_files:
52
+ - History.txt
53
+ - Manifest.txt
54
+ - README.txt
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ requirements: []
60
+
61
+ dependencies:
62
+ - !ruby/object:Gem::Dependency
63
+ name: activerecord
64
+ version_requirement:
65
+ version_requirements: !ruby/object:Gem::Version::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 1.15.3
70
+ version:
71
+ - !ruby/object:Gem::Dependency
72
+ name: hoe
73
+ version_requirement:
74
+ version_requirements: !ruby/object:Gem::Version::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 1.3.0
79
+ version: