attr_bucket 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,2 +1,8 @@
1
1
  require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
2
4
  Bundler::GemHelper.install_tasks
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
data/attr_bucket.gemspec CHANGED
@@ -12,7 +12,9 @@ Gem::Specification.new do |s|
12
12
  s.summary = %q{Your model can has a bucket (for its attributes).}
13
13
  s.description = %q{Store a few extra (non-searchable) attributes away in a bucket. This is probably a horrible idea, but try it anyway.}
14
14
 
15
- s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0"])
15
+ s.add_runtime_dependency 'activerecord', '~> 3.0.0'
16
+ s.add_development_dependency 'rspec', '~> 2.4.0'
17
+ s.add_development_dependency 'sqlite3'
16
18
 
17
19
  s.rubyforge_project = "attr_bucket"
18
20
 
data/lib/attr_bucket.rb CHANGED
@@ -14,6 +14,22 @@ module AttrBucket
14
14
  read_attribute(name)
15
15
  end
16
16
 
17
+ def valid_class(value, type)
18
+ case type
19
+ when :integer then Fixnum === value
20
+ when :float then Float === value
21
+ when :decimal then BigDecimal === value
22
+ when :datetime then Time === value
23
+ when :date then Date === value
24
+ when :timestamp then Time === value
25
+ when :time then Time === value
26
+ when :text, :string then String === value
27
+ when :binary then String === value
28
+ when :boolean then [TrueClass, FalseClass].grep value
29
+ else false
30
+ end
31
+ end
32
+
17
33
  # Swipe the nifty column typecasting from the column class
18
34
  # underlying the bucket column, or use the call method of
19
35
  # the object supplied for +type+ if it responds to call.
@@ -25,7 +41,7 @@ module AttrBucket
25
41
 
26
42
  return type.call(value) if type.respond_to?(:call)
27
43
 
28
- case type
44
+ typecasted = case type
29
45
  when :string then value.to_s
30
46
  when :text then value.to_s
31
47
  when :integer then value.to_i rescue value ? 1 : 0
@@ -39,6 +55,10 @@ module AttrBucket
39
55
  when :boolean then column_class.value_to_boolean(value)
40
56
  else value
41
57
  end
58
+
59
+ raise ArgumentError, "Unable to typecast #{value} to #{type}" unless valid_class(typecasted, type)
60
+
61
+ typecasted
42
62
  end
43
63
 
44
64
  module ClassMethods
@@ -107,6 +127,7 @@ module AttrBucket
107
127
  define_method "#{attr_name}=" do |val|
108
128
  # TODO: Make this more resilient/granular for multiple bucketed changes
109
129
  send("#{bucket_name}_will_change!")
130
+ typecasted = explicitly_type_cast(val, attr_type, column_class)
110
131
  get_attr_bucket(bucket_name)[attr_name] = explicitly_type_cast(val, attr_type, column_class)
111
132
  end unless method_defined? "#{attr_name}="
112
133
  end
@@ -1,3 +1,3 @@
1
1
  module AttrBucket
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+
3
+ describe AttrBucket do
4
+
5
+ it 'should define an private attr_bucket method in AR::Base' do
6
+ ActiveRecord::Base.private_methods.should include :attr_bucket
7
+ end
8
+
9
+ it 'should define an i_has_a_bucket alias in AR::Base' do
10
+ ActiveRecord::Base.private_methods.should include :i_has_a_bucket
11
+ end
12
+
13
+ it 'should raise an ArgumentError when defining a bucket on a non-text column' do
14
+ expect { a_class_with_bucket :name => :blah }.to raise_error ArgumentError
15
+ end
16
+
17
+ context 'object with a bucketed attribute named "nickname"' do
18
+ before do
19
+ @o = an_object_with_bucket :bucket => :nickname
20
+ end
21
+
22
+ it 'should cast nickname to string' do
23
+ @o.nickname = 42
24
+ @o.nickname.should eq '42'
25
+ end
26
+
27
+ it 'should support validations' do
28
+ @o.class.validates_presence_of :nickname
29
+ expect { @o.save! }.to raise_error ActiveRecord::RecordInvalid
30
+ end
31
+
32
+ it 'should maintain bucketed attributes when saved' do
33
+ @o.nickname = 'Headly von Headenstein'
34
+ @o.save
35
+
36
+ persisted_item.nickname.should eq 'Headly von Headenstein'
37
+ end
38
+ end
39
+
40
+ context 'object with bucketed attributes in array format' do
41
+ before do
42
+ @o = an_object_with_bucket :bucket => [:quest, :favorite_color]
43
+ end
44
+
45
+ it 'should cast all values to strings' do
46
+ @o.quest = 1
47
+ @o.favorite_color = 2
48
+
49
+ [@o.quest, @o.favorite_color].should eq ['1', '2']
50
+ end
51
+ end
52
+
53
+ context 'object with bucketed attributes in hash format' do
54
+ before do
55
+ @o = an_object_with_bucket :bucket => {
56
+ :summary => :text,
57
+ :age => :integer,
58
+ :body_temp => :float,
59
+ :salary => :decimal,
60
+ :hired_at => :datetime,
61
+ :stamp => :timestamp,
62
+ :workday_starts_at => :time,
63
+ :birthday => :date,
64
+ :binary_data => :binary,
65
+ :is_awesome => :boolean,
66
+ :processed_name => proc { |val| "PROCESSED: #{val}" }
67
+ }
68
+ end
69
+
70
+ it 'typecasts to String for :text' do
71
+ @o.summary = 12345
72
+ @o.summary.should be_a String
73
+ @o.summary.should eq '12345'
74
+ end
75
+
76
+ it 'typecasts to Fixnum for :integer' do
77
+ @o.age = '33'
78
+ @o.age.should be_a Fixnum
79
+ @o.age.should eq 33
80
+ end
81
+
82
+ it 'typecasts to Float for :float' do
83
+ @o.body_temp = '98.6'
84
+ @o.body_temp.should be_a Float
85
+ @o.body_temp.should eq 98.6
86
+ end
87
+
88
+ it 'typecasts to BigDecimal for :decimal' do
89
+ @o.salary = '50000.23'
90
+ @o.salary.should be_a BigDecimal
91
+ @o.salary.should eq 50000.23
92
+ end
93
+
94
+ it 'typecasts to Time for :datetime' do
95
+ @o.hired_at = '2011-01-01 08:00:00'
96
+ @o.hired_at.should be_a Time
97
+ @o.hired_at.should eq Time.parse '2011-01-01 08:00:00'
98
+ end
99
+
100
+ it 'typecasts to Time for :timestamp' do
101
+ @o.stamp = '2011-01-01 08:00:00'
102
+ @o.stamp.should be_a Time
103
+ @o.stamp.should eq Time.parse '2011-01-01 08:00:00'
104
+ end
105
+
106
+ it 'typecasts to dummy Time for :time' do
107
+ @o.workday_starts_at = '08:00:00'
108
+ @o.workday_starts_at.should be_a Time
109
+ @o.workday_starts_at.should eq Time.parse '2000-01-01 08:00:00'
110
+ end
111
+
112
+ it 'typecasts to Date for :date in string format' do
113
+ @o.birthday = '1977/8/29'
114
+ @o.birthday.should be_a Date
115
+ @o.birthday.should eq Date.new(1977, 8, 29)
116
+ end
117
+
118
+ it 'typecasts to String for :binary' do
119
+ @o.binary_data = File.read(__FILE__)
120
+ @o.binary_data.should be_a String
121
+ @o.binary_data.should match /@o.binary_data.should match/ # ooh, meta.
122
+ end
123
+
124
+ it 'typecasts to TrueClass/FalseClass for :boolean' do
125
+ @o.is_awesome = '1'
126
+ @o.should be_awesome
127
+ end
128
+
129
+ it 'performs custom processing when an attribute has a proc "type"' do
130
+ @o.processed_name = 'Ernie'
131
+ @o.processed_name.should be_a String
132
+ @o.processed_name.should eq 'PROCESSED: Ernie'
133
+ end
134
+
135
+ it 'should raise ArgumentError if unable to typecast a value' do
136
+ expect { @o.stamp = 123456 }.to raise_error ArgumentError
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,15 @@
1
+ module AttrBucketHelper
2
+ def a_class_with_bucket(opts)
3
+ Item.delete_all
4
+ Object.send :remove_const, :AttrBucketItem if Object.const_defined? :AttrBucketItem
5
+ Object.const_set :AttrBucketItem, Class.new(Item) { attr_bucket opts }
6
+ end
7
+
8
+ def an_object_with_bucket(opts)
9
+ a_class_with_bucket(opts).new
10
+ end
11
+
12
+ def persisted_item
13
+ AttrBucketItem.first
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'attr_bucket'
4
+
5
+ Dir[File.expand_path('../{helpers,support}/*.rb', __FILE__)].each do |f|
6
+ require f
7
+ end
8
+
9
+ RSpec.configure do |config|
10
+ config.before :suite do
11
+ Schema.create
12
+ end
13
+
14
+ config.include AttrBucketHelper
15
+ end
@@ -0,0 +1,27 @@
1
+ ActiveRecord::Base.establish_connection(
2
+ :adapter => 'sqlite3',
3
+ :database => ':memory:'
4
+ )
5
+
6
+ class Item < ActiveRecord::Base
7
+ def awesome?
8
+ respond_to?(:is_awesome) && is_awesome
9
+ end
10
+ end
11
+
12
+ module Schema
13
+ def self.create
14
+ ActiveRecord::Base.silence do
15
+ ActiveRecord::Migration.verbose = false
16
+
17
+ ActiveRecord::Schema.define do
18
+ create_table :items, :force => true do |t|
19
+ t.string :name
20
+ t.string :type
21
+ t.text :bucket
22
+ t.text :other_bucket
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
7
  - 2
9
- version: 0.1.2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ernie Miller
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-28 00:00:00 -05:00
17
+ date: 2011-01-29 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,34 @@ dependencies:
32
32
  version: 3.0.0
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 2
45
+ - 4
46
+ - 0
47
+ version: 2.4.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: sqlite3
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
35
63
  description: Store a few extra (non-searchable) attributes away in a bucket. This is probably a horrible idea, but try it anyway.
36
64
  email:
37
65
  - ernie@metautonomo.us
@@ -50,6 +78,10 @@ files:
50
78
  - attr_bucket.gemspec
51
79
  - lib/attr_bucket.rb
52
80
  - lib/attr_bucket/version.rb
81
+ - spec/attr_bucket_spec.rb
82
+ - spec/helpers/attr_bucket_helper.rb
83
+ - spec/spec_helper.rb
84
+ - spec/support/schema.rb
53
85
  has_rdoc: true
54
86
  homepage: http://metautonomo.us
55
87
  licenses: []
@@ -82,5 +114,8 @@ rubygems_version: 1.3.7
82
114
  signing_key:
83
115
  specification_version: 3
84
116
  summary: Your model can has a bucket (for its attributes).
85
- test_files: []
86
-
117
+ test_files:
118
+ - spec/attr_bucket_spec.rb
119
+ - spec/helpers/attr_bucket_helper.rb
120
+ - spec/spec_helper.rb
121
+ - spec/support/schema.rb