constantrecord 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.rdoc +31 -7
- data/Rakefile +42 -13
- data/VERSION +1 -0
- data/constantrecord.gemspec +29 -11
- data/lib/constantrecord.rb +93 -47
- data/test/helper.rb +26 -0
- data/test/{constantrecord_test.rb → test_constantrecord.rb} +38 -3
- metadata +23 -21
- data/Manifest +0 -6
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Christoph Petschnig
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
= ConstantRecord
|
2
2
|
|
3
|
+
A tiny ActiveRecord substitute for small, never changing database tables.
|
4
|
+
|
3
5
|
== Usage
|
4
6
|
|
5
7
|
class Currency < ConstantRecord::Base
|
@@ -9,7 +11,7 @@
|
|
9
11
|
or
|
10
12
|
|
11
13
|
class MoreDetailedCurrency < ConstantRecord::Base
|
12
|
-
columns :
|
14
|
+
columns :name, :description
|
13
15
|
data ['EUR', 'Euro'],
|
14
16
|
['USD', 'United States dollar'],
|
15
17
|
['CAD', 'Canadian dollar'],
|
@@ -22,6 +24,7 @@ Inside ActiveRecord, it works just like a "normal" ActiveRecord association:
|
|
22
24
|
|
23
25
|
class Invoice < ActiveRecord::Base
|
24
26
|
belongs_to :currency # via currency_id database column
|
27
|
+
validates_inclusion_of :currency_id, :in => Currency.ids
|
25
28
|
|
26
29
|
def print_currency
|
27
30
|
# Currency#name is the default attribute
|
@@ -39,10 +42,10 @@ In my current application, my main/parent class has about 35 child classes,
|
|
39
42
|
that use over 40 different constant classes. The use of ConstantRecord meant
|
40
43
|
an estimated 15 to 20 per cent speed gain for my application.
|
41
44
|
|
42
|
-
ConstantRecord classes don't need
|
45
|
+
ConstantRecord classes don't need associations:
|
43
46
|
|
44
47
|
class CanadianProvince < ConstantRecord::Base
|
45
|
-
data
|
48
|
+
data 'Alberta', ...
|
46
49
|
has_many :people # is not necessary, will not work
|
47
50
|
end
|
48
51
|
|
@@ -51,8 +54,12 @@ If you want to fetch all people living in Alberta, use:
|
|
51
54
|
Person.find(:all, :conditions =>
|
52
55
|
{:province_id => CanadianProvince.find_by_name('Alberta').id}
|
53
56
|
|
57
|
+
or, in Rails 3:
|
58
|
+
|
59
|
+
Person.where(:province_id => CanadianProvince.find_by_name('Alberta').id)
|
60
|
+
|
54
61
|
If you ever think, ConstantRecord lacks key features of ActiveRecord, (submit
|
55
|
-
a patch or) create the table and derive
|
62
|
+
a patch or) create the table and derive the class from ActiveRecord instead.
|
56
63
|
This is a key design objective for ConstantRecord.
|
57
64
|
|
58
65
|
== Features
|
@@ -64,14 +71,14 @@ When +data+ is a simple Array, #name is the default attribute.
|
|
64
71
|
|
65
72
|
MoreDetailedCurrency.find(3) >> #<MoreDetailedCurrency:0x2c8d94c
|
66
73
|
@description="Canadian Dollar",
|
67
|
-
@id=3, @
|
74
|
+
@id=3, @name="CAD">
|
68
75
|
|
69
76
|
Currency.find_by_name('CHF') >> #<Currency:0x2c86ef8 @id=3, @name="CHF">
|
70
77
|
|
71
|
-
MoreDetailedCurrency.
|
78
|
+
MoreDetailedCurrency.find_by_name('CAD')
|
72
79
|
>> #<MoreDetailedCurrency:0x2c8d94c
|
73
80
|
@description="Canadian Dollar",
|
74
|
-
@id=3, @
|
81
|
+
@id=3, @name="CAD">
|
75
82
|
|
76
83
|
Currency.count :all >> 5
|
77
84
|
|
@@ -85,3 +92,20 @@ ActiveRecord compatible. In a Form you can use:
|
|
85
92
|
or
|
86
93
|
|
87
94
|
<%= f.select :currency_id, Currency.options_for_select(:include_null => true) %>
|
95
|
+
|
96
|
+
If you want to store the name instead of the ID, then you can use:
|
97
|
+
|
98
|
+
<%= f.select :currency_id, Currency.options_for_select(:value => :name) %>
|
99
|
+
|
100
|
+
In this case, you must also change your validation:
|
101
|
+
|
102
|
+
class Invoice < ActiveRecord::Base
|
103
|
+
validates_inclusion_of :currency_id, :in => Currency.names
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
== Copyright
|
108
|
+
|
109
|
+
Copyright (c) 2009 Christoph Petschnig. See LICENSE for details.
|
110
|
+
|
111
|
+
Thanks to Till Salzer, Torsten Schönebaum and Nate Wiger for contributions!
|
data/Rakefile
CHANGED
@@ -1,23 +1,52 @@
|
|
1
|
-
# Rakefile for constantrecord
|
2
1
|
require 'rubygems'
|
3
2
|
require 'rake'
|
4
|
-
require 'echoe'
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "constantrecord"
|
8
|
+
gem.summary = %Q{A tiny ActiveRecord substitute for small, never changing database tables.}
|
9
|
+
gem.description = %Q{A tiny ActiveRecord substitute for small, never changing database tables.}
|
10
|
+
gem.email = "info@purevirtual.de"
|
11
|
+
gem.homepage = "http://github.com/cpetschnig/constantrecord"
|
12
|
+
gem.authors = ["Christoph Petschnig"]
|
13
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
14
|
+
end
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
14
18
|
end
|
15
19
|
|
16
|
-
|
20
|
+
require 'rake/testtask'
|
21
|
+
Rake::TestTask.new(:test) do |test|
|
22
|
+
test.libs << 'lib' << 'test'
|
23
|
+
test.pattern = 'test/**/test_*.rb'
|
24
|
+
test.verbose = true
|
25
|
+
end
|
17
26
|
|
27
|
+
begin
|
28
|
+
require 'rcov/rcovtask'
|
29
|
+
Rcov::RcovTask.new do |test|
|
30
|
+
test.libs << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
rescue LoadError
|
35
|
+
task :rcov do
|
36
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
37
|
+
end
|
38
|
+
end
|
18
39
|
|
19
|
-
task :
|
40
|
+
task :test => :check_dependencies
|
20
41
|
|
21
|
-
|
42
|
+
task :default => :test
|
22
43
|
|
44
|
+
require 'rake/rdoctask'
|
45
|
+
Rake::RDocTask.new do |rdoc|
|
46
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
23
47
|
|
48
|
+
rdoc.rdoc_dir = 'rdoc'
|
49
|
+
rdoc.title = "constantrecord #{version}"
|
50
|
+
rdoc.rdoc_files.include('README*')
|
51
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
52
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
data/constantrecord.gemspec
CHANGED
@@ -1,31 +1,49 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
1
4
|
# -*- encoding: utf-8 -*-
|
2
5
|
|
3
6
|
Gem::Specification.new do |s|
|
4
7
|
s.name = %q{constantrecord}
|
5
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
6
9
|
|
7
|
-
s.required_rubygems_version = Gem::Requirement.new(">=
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
11
|
s.authors = ["Christoph Petschnig"]
|
9
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-06-29}
|
10
13
|
s.description = %q{A tiny ActiveRecord substitute for small, never changing database tables.}
|
11
14
|
s.email = %q{info@purevirtual.de}
|
12
|
-
s.extra_rdoc_files = [
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"LICENSE",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"constantrecord.gemspec",
|
25
|
+
"lib/constantrecord.rb",
|
26
|
+
"test/helper.rb",
|
27
|
+
"test/test_constantrecord.rb"
|
28
|
+
]
|
29
|
+
s.homepage = %q{http://github.com/cpetschnig/constantrecord}
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
16
31
|
s.require_paths = ["lib"]
|
17
|
-
s.
|
18
|
-
s.rubygems_version = %q{1.3.6}
|
32
|
+
s.rubygems_version = %q{1.3.7}
|
19
33
|
s.summary = %q{A tiny ActiveRecord substitute for small, never changing database tables.}
|
20
|
-
s.test_files = [
|
34
|
+
s.test_files = [
|
35
|
+
"test/test_constantrecord.rb",
|
36
|
+
"test/helper.rb"
|
37
|
+
]
|
21
38
|
|
22
39
|
if s.respond_to? :specification_version then
|
23
40
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
24
41
|
s.specification_version = 3
|
25
42
|
|
26
|
-
if Gem::Version.new(Gem::
|
43
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
44
|
else
|
28
45
|
end
|
29
46
|
else
|
30
47
|
end
|
31
48
|
end
|
49
|
+
|
data/lib/constantrecord.rb
CHANGED
@@ -1,27 +1,8 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright (c) 2009 Christoph Petschnig
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
-
# a copy of this software and associated documentation files (the
|
6
|
-
# "Software"), to deal in the Software without restriction, including
|
7
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
-
# the following 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 OF
|
17
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
-
#++
|
23
|
-
|
24
1
|
module ConstantRecord #:nodoc:
|
2
|
+
|
3
|
+
class ConstantNotFound < StandardError; end #:nodoc:
|
4
|
+
class LoggerError < StandardError; end #:nodoc:
|
5
|
+
|
25
6
|
# ConstantRecord::Base is a tiny ActiveRecord substitute for small, never
|
26
7
|
# changing database tables.
|
27
8
|
#
|
@@ -34,7 +15,7 @@ module ConstantRecord #:nodoc:
|
|
34
15
|
# or
|
35
16
|
#
|
36
17
|
# class MoreDetailedCurrency < ConstantRecord::Base
|
37
|
-
# columns :
|
18
|
+
# columns :name, :description
|
38
19
|
# data ['EUR', 'Euro'],
|
39
20
|
# ['USD', 'US Dollar'],
|
40
21
|
# ['CAD', 'Canadian Dollar'],
|
@@ -59,23 +40,15 @@ module ConstantRecord #:nodoc:
|
|
59
40
|
def self.columns(*args)
|
60
41
|
# remove the default column name
|
61
42
|
undef_method :name
|
43
|
+
class << self
|
44
|
+
undef_method :names
|
45
|
+
end
|
62
46
|
|
63
|
-
|
64
|
-
col_ar = args.collect do |column|
|
65
|
-
raise TypeError.new("You can only pass Symbol or String object to #{self}::columns.") unless column.kind_of?(Symbol) || column.kind_of?(String)
|
66
|
-
|
67
|
-
class_eval do
|
68
|
-
private
|
69
|
-
attr_writer column
|
70
|
-
public
|
71
|
-
attr_reader column
|
72
|
-
end
|
73
|
-
|
74
|
-
i += 1
|
75
|
-
[column.to_sym, i - 1]
|
76
|
-
end.flatten
|
47
|
+
col_ar = build_column_methods(*args)
|
77
48
|
|
78
49
|
@columns = Hash[*col_ar]
|
50
|
+
|
51
|
+
build_array_over_column_methods
|
79
52
|
end
|
80
53
|
|
81
54
|
# Set the data. Arguments must be an Array.
|
@@ -177,7 +150,7 @@ module ConstantRecord #:nodoc:
|
|
177
150
|
# calculate the maximum width of each column
|
178
151
|
max_size = []
|
179
152
|
cols.each do |index, name|
|
180
|
-
woci =
|
153
|
+
woci = width_of_column(index)
|
181
154
|
max_size << (woci > name.to_s.length ? woci : name.to_s.length)
|
182
155
|
end
|
183
156
|
|
@@ -197,14 +170,14 @@ module ConstantRecord #:nodoc:
|
|
197
170
|
|
198
171
|
# Keep this to spot problems in integration with ActiveRecord
|
199
172
|
def method_missing(symbol, *args) #:nodoc:
|
200
|
-
|
173
|
+
self.class.log(:debug, "#{self.class}#method_missing(:#{symbol})")
|
201
174
|
super symbol, *args
|
202
175
|
end
|
203
176
|
|
204
177
|
# Keep this to spot problems in integration with ActiveRecord
|
205
178
|
def respond_to?(symbol) #:nodoc:
|
206
179
|
result = super(symbol)
|
207
|
-
|
180
|
+
self.class.log(:debug, "#{self.class}#respond_to?(:#{symbol}) => #{result}") if !result
|
208
181
|
result
|
209
182
|
end
|
210
183
|
|
@@ -213,14 +186,14 @@ module ConstantRecord #:nodoc:
|
|
213
186
|
if /^find_by_([_a-zA-Z]\w*)$/ =~ (symbol.to_s)
|
214
187
|
return find(:first, :conditions => {$1.to_sym => args[0]})
|
215
188
|
end
|
216
|
-
|
189
|
+
self.log(:debug, "#{self}::method_missing(:#{symbol})")
|
217
190
|
super symbol, *args
|
218
191
|
end
|
219
192
|
|
220
193
|
# Keep this to spot problems in integration with ActiveRecord
|
221
194
|
def self.respond_to?(symbol) #:nodoc:
|
222
195
|
result = super symbol
|
223
|
-
|
196
|
+
self.log(:debug, "#{self}::respond_to?(:#{symbol}) => #{result}") if !result
|
224
197
|
result
|
225
198
|
end
|
226
199
|
|
@@ -234,7 +207,7 @@ module ConstantRecord #:nodoc:
|
|
234
207
|
# With the class:
|
235
208
|
#
|
236
209
|
# class Currency < ConstantRecord::Base
|
237
|
-
# columns :
|
210
|
+
# columns :name, :description
|
238
211
|
# data ['EUR', 'Euro'],
|
239
212
|
# ['USD', 'US Dollar']
|
240
213
|
# end
|
@@ -253,8 +226,8 @@ module ConstantRecord #:nodoc:
|
|
253
226
|
# While:
|
254
227
|
#
|
255
228
|
# <%= f.select :currency_id, Currency.options_for_select(
|
256
|
-
# :display => Proc.new { |obj| "#{obj.
|
257
|
-
# :value => :
|
229
|
+
# :display => Proc.new { |obj| "#{obj.name} (#{obj.description})" },
|
230
|
+
# :value => :name, :include_null => true,
|
258
231
|
# :null_text => 'Please choose one', :null_value => nil ) %>
|
259
232
|
#
|
260
233
|
# Results to:
|
@@ -305,6 +278,32 @@ module ConstantRecord #:nodoc:
|
|
305
278
|
result
|
306
279
|
end
|
307
280
|
|
281
|
+
# Returns an array of the first column of your data. This method will be
|
282
|
+
# removed, if you override your class with +columns+, that do not include
|
283
|
+
# a column called :name
|
284
|
+
def self.names
|
285
|
+
@data.map(&:first)
|
286
|
+
end
|
287
|
+
|
288
|
+
# Returns an array of all ids
|
289
|
+
def self.ids
|
290
|
+
ret = []
|
291
|
+
@data.length.times{|n| ret << n+1}
|
292
|
+
ret
|
293
|
+
end
|
294
|
+
|
295
|
+
# Get the logger
|
296
|
+
def self.logger
|
297
|
+
@@logger
|
298
|
+
end
|
299
|
+
|
300
|
+
# Set the logger; ConstantRecord will try to use the Rails logger, if it's
|
301
|
+
# there. Otherwise an error will be raised; set your own logger by calling
|
302
|
+
# ConstantRecord::Base.logger = MyAwesomeLogger.new
|
303
|
+
def self.logger=(value)
|
304
|
+
@@logger = value
|
305
|
+
end
|
306
|
+
|
308
307
|
private
|
309
308
|
|
310
309
|
# Get the name of the columns or the default value
|
@@ -335,7 +334,7 @@ module ConstantRecord #:nodoc:
|
|
335
334
|
self.new(id, *@data[id - 1])
|
336
335
|
end
|
337
336
|
|
338
|
-
def self.
|
337
|
+
def self.width_of_column(index)
|
339
338
|
return @data.size.to_s.length if index == 0
|
340
339
|
result = 0
|
341
340
|
@data.each do |row|
|
@@ -345,5 +344,52 @@ module ConstantRecord #:nodoc:
|
|
345
344
|
result
|
346
345
|
end
|
347
346
|
|
347
|
+
# Build the attributes for columns;
|
348
|
+
# Returns an array in the form: [[:name_of_column_1, 0], [:name_of_column_2, 1], ...
|
349
|
+
def self.build_column_methods(*args)
|
350
|
+
i = 0
|
351
|
+
args.collect do |column|
|
352
|
+
raise TypeError.new("You can only pass Symbol or String object to #{self}::columns.") unless column.kind_of?(Symbol) || column.kind_of?(String)
|
353
|
+
|
354
|
+
# TODO: warn, if methods already exist!!
|
355
|
+
|
356
|
+
class_eval do
|
357
|
+
private
|
358
|
+
attr_writer column
|
359
|
+
public
|
360
|
+
attr_reader column
|
361
|
+
end
|
362
|
+
|
363
|
+
i += 1
|
364
|
+
[column.to_sym, i - 1]
|
365
|
+
end.flatten
|
366
|
+
end
|
367
|
+
|
368
|
+
# Create a class method for every column;
|
369
|
+
# class UsState with columns :name, :short_form will give you the methods
|
370
|
+
# :names and :short_forms, which will return an array of their column values
|
371
|
+
def self.build_array_over_column_methods
|
372
|
+
@columns.each do |column, column_index|
|
373
|
+
# try to use (most likely) ActiveSupport inflections, if possible
|
374
|
+
pluralized_name = if String.new.respond_to? :pluralize
|
375
|
+
column.to_s.pluralize
|
376
|
+
else
|
377
|
+
"#{column}s" # better than nothing
|
378
|
+
end
|
379
|
+
|
380
|
+
if self.class.method_defined?(pluralized_name)
|
381
|
+
self.log :warn, "Warning!!! Method #{self}##{pluralized_name} is already defined. Consider using a different column name!"
|
382
|
+
end
|
383
|
+
|
384
|
+
class_eval "def self.#{pluralized_name}; @data.map{|obj| obj[#{column_index}]}; end"
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
def self.log(level, msg)
|
389
|
+
@@logger ||= Rails.logger if defined?(Rails) # TODO: take a more generic approach; at least try to include Sinatra, Padrino loggers or the Rack logger
|
390
|
+
raise LoggerError unless @@logger && @@logger.respond_to?(level)
|
391
|
+
@@logger.send(level, msg)
|
392
|
+
end
|
393
|
+
|
348
394
|
end
|
349
395
|
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
require 'constantrecord'
|
7
|
+
|
8
|
+
class Test::Unit::TestCase
|
9
|
+
end
|
10
|
+
|
11
|
+
# simply count, how often each log type gets called
|
12
|
+
class MyTestLogger
|
13
|
+
TYPES = %w{debug info warn error fatal}
|
14
|
+
def initialize
|
15
|
+
TYPES.each{|type|instance_variable_set "@#{type}_count", 0}
|
16
|
+
end
|
17
|
+
TYPES.each do |type|
|
18
|
+
attr_reader "#{type}_count"
|
19
|
+
eval "def #{type}(*args); @#{type}_count += 1; end"
|
20
|
+
#eval "def #{type}(*args); puts *args; @#{type}_count += 1; end" # print out log messages for better debugging!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
ConstantRecord::Base.logger = MyTestLogger.new
|
26
|
+
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'test/unit'
|
1
|
+
require 'helper'
|
3
2
|
|
4
3
|
class SimpleClass < ConstantRecord::Base
|
5
4
|
data 'Lithuania', 'Latvia', 'Estonia'
|
@@ -28,6 +27,18 @@ class MultiColumnClassNotString < ConstantRecord::Base
|
|
28
27
|
[19, false]
|
29
28
|
end
|
30
29
|
|
30
|
+
class ForValidation < ConstantRecord::Base
|
31
|
+
columns :name, :value
|
32
|
+
data ['normal', 1],
|
33
|
+
['gift', 2],
|
34
|
+
['friend', 3]
|
35
|
+
end
|
36
|
+
|
37
|
+
class BadColumnNames < ConstantRecord::Base
|
38
|
+
# columns :instance_method, :class_variable
|
39
|
+
# data ['foo', 'bar']
|
40
|
+
end
|
41
|
+
|
31
42
|
class TestConstantRecord < Test::Unit::TestCase
|
32
43
|
def test_simple_finder
|
33
44
|
assert_equal 'Estonia', SimpleClass.find(3).name
|
@@ -54,6 +65,7 @@ class TestConstantRecord < Test::Unit::TestCase
|
|
54
65
|
assert_equal 'Sgt. Pepper', SimpleClass2.find_by_album('Sgt. Pepper').album
|
55
66
|
assert_equal 1, SimpleClass2.find_by_album('Sgt. Pepper').id
|
56
67
|
assert_raise (RuntimeError) { SimpleClass2.find_by_name('Sgt. Pepper') }
|
68
|
+
assert_raise (NoMethodError) { SimpleClass2.find(1).name }
|
57
69
|
assert_equal [ 'Sgt. Pepper', 'Magical Mystery Tour', 'Abbey Road' ], SimpleClass2.find(:all).collect{|o| o.album}
|
58
70
|
assert_equal [ 1, 2, 3 ], SimpleClass2.find(:all).collect{|o| o.id}
|
59
71
|
assert_equal 3, SimpleClass2.count
|
@@ -102,4 +114,27 @@ class TestConstantRecord < Test::Unit::TestCase
|
|
102
114
|
def test_all_shortcut
|
103
115
|
assert_equal SimpleClass.find(:all).collect{|o| o.name}, SimpleClass.all.collect{|o| o.name}
|
104
116
|
end
|
105
|
-
|
117
|
+
|
118
|
+
def test_validation_methods
|
119
|
+
# validates_inclusion_of :thingy, :in => ForValidation.names
|
120
|
+
assert_equal ['normal','gift','friend'], ForValidation.names
|
121
|
+
assert_equal [1,2,3], ForValidation.values
|
122
|
+
assert_equal [1,2,3,4,5], MultiColumnClass.ids
|
123
|
+
assert_equal ['Sgt. Pepper', 'Magical Mystery Tour', 'Abbey Road'], SimpleClass2.albums
|
124
|
+
assert_equal %w{EUR USD CAD GBP CHF}, MultiColumnClass.shorts
|
125
|
+
assert_raise (NoMethodError) { MultiColumnClass.names }
|
126
|
+
assert_raise (NoMethodError) { MultiColumnClass.values }
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_logger
|
130
|
+
assert_nothing_raised { ConstantRecord::Base.logger = MyTestLogger.new }
|
131
|
+
assert_nothing_raised { SimpleClass.respond_to?(:asdfghjkl) }
|
132
|
+
assert_nothing_raised { MultiColumnClass.find(1).respond_to?(:asdfghjkl) }
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_bad_colum_names
|
136
|
+
warnings_count = ConstantRecord::Base.logger.warn_count
|
137
|
+
BadColumnNames.columns :instance_method, :class_variable # must log 2 warnings
|
138
|
+
assert_equal ConstantRecord::Base.logger.warn_count - warnings_count, 2
|
139
|
+
end
|
140
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: constantrecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
- 1
|
8
8
|
- 2
|
9
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Christoph Petschnig
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-06-29 00:00:00 +02:00
|
18
19
|
default_executable:
|
19
20
|
dependencies: []
|
20
21
|
|
@@ -25,50 +26,51 @@ executables: []
|
|
25
26
|
extensions: []
|
26
27
|
|
27
28
|
extra_rdoc_files:
|
28
|
-
-
|
29
|
+
- LICENSE
|
29
30
|
- README.rdoc
|
30
31
|
files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
- Rakefile
|
35
|
+
- VERSION
|
31
36
|
- constantrecord.gemspec
|
32
37
|
- lib/constantrecord.rb
|
33
|
-
- test/
|
34
|
-
-
|
35
|
-
- Rakefile
|
36
|
-
- README.rdoc
|
38
|
+
- test/helper.rb
|
39
|
+
- test/test_constantrecord.rb
|
37
40
|
has_rdoc: true
|
38
|
-
homepage: http://github.com/
|
41
|
+
homepage: http://github.com/cpetschnig/constantrecord
|
39
42
|
licenses: []
|
40
43
|
|
41
44
|
post_install_message:
|
42
45
|
rdoc_options:
|
43
|
-
- --
|
44
|
-
- --inline-source
|
45
|
-
- --title
|
46
|
-
- Constantrecord
|
47
|
-
- --main
|
48
|
-
- README.rdoc
|
46
|
+
- --charset=UTF-8
|
49
47
|
require_paths:
|
50
48
|
- lib
|
51
49
|
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
52
51
|
requirements:
|
53
52
|
- - ">="
|
54
53
|
- !ruby/object:Gem::Version
|
54
|
+
hash: 3
|
55
55
|
segments:
|
56
56
|
- 0
|
57
57
|
version: "0"
|
58
58
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
59
60
|
requirements:
|
60
61
|
- - ">="
|
61
62
|
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
62
64
|
segments:
|
63
|
-
-
|
64
|
-
|
65
|
-
version: "1.2"
|
65
|
+
- 0
|
66
|
+
version: "0"
|
66
67
|
requirements: []
|
67
68
|
|
68
|
-
rubyforge_project:
|
69
|
-
rubygems_version: 1.3.
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.7
|
70
71
|
signing_key:
|
71
72
|
specification_version: 3
|
72
73
|
summary: A tiny ActiveRecord substitute for small, never changing database tables.
|
73
74
|
test_files:
|
74
|
-
- test/
|
75
|
+
- test/test_constantrecord.rb
|
76
|
+
- test/helper.rb
|