setsumei 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,8 @@ require 'setsumei/describable/string_attribute'
3
3
  require 'setsumei/describable/float_attribute'
4
4
  require 'setsumei/describable/int_attribute'
5
5
  require 'setsumei/describable/object_attribute'
6
+ require 'setsumei/describable/time_attribute'
7
+ require 'setsumei/describable/date_attribute'
6
8
  require 'setsumei/describable/collection'
7
9
 
8
10
  module Setsumei
@@ -66,15 +68,20 @@ module Setsumei
66
68
  end
67
69
  def attribute_type(type)
68
70
  case type
69
- when :boolean then BooleanAttribute
70
- when :string then StringAttribute
71
- when nil then StringAttribute
72
- when :float then FloatAttribute
73
- when :int then IntAttribute
71
+ when :boolean then BooleanAttribute
72
+ when :string then StringAttribute
73
+ when nil then StringAttribute
74
+ when :float then FloatAttribute
75
+ when :int then IntAttribute
76
+ when :date then DateAttribute
77
+ when :time then TimeAttribute
74
78
  else
75
- ObjectAttribute if type.is_a?(Class)
79
+ object_attribute_if_a_class(type) or raise(ArgumentError)
76
80
  end
77
81
  end
82
+ def object_attribute_if_a_class(type)
83
+ (type.is_a?(Class) && ObjectAttribute)
84
+ end
78
85
  end
79
86
  end
80
87
  end
@@ -0,0 +1,40 @@
1
+ module Setsumei
2
+ module Describable
3
+ class DateAttribute
4
+ def DateAttribute.named(name,options = {})
5
+ options = options.dup
6
+ new.tap do |attribute|
7
+ attribute.name = name
8
+ attribute.format = options.delete(:format) || '%Y-%m-%d'
9
+ attribute.lookup_key = options.delete(:from_within)
10
+ attribute.options = options.tap { |o| o.delete :as_a }
11
+ end
12
+ end
13
+
14
+ attr_accessor :name, :options, :lookup_key, :format
15
+
16
+ def is_an_attribute_of_type?(type)
17
+ type == :date || type == self.class
18
+ end
19
+
20
+ def value_for(pre_type_cast_value)
21
+ Date.strptime pre_type_cast_value, format
22
+ end
23
+
24
+ def set_value_on(object, options)
25
+ object.send accessor, value_from_hash(options[:from_value_in])
26
+ end
27
+
28
+ private
29
+ def accessor
30
+ :"#{name}="
31
+ end
32
+ def value_from_hash(hash)
33
+ value_for hash[ key_for(hash)]
34
+ end
35
+ def key_for(hash)
36
+ lookup_key || Build::Key.for(name, given: hash.keys)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ module Setsumei
2
+ module Describable
3
+ class TimeAttribute
4
+ def TimeAttribute.named(name,options = {})
5
+ options = options.dup
6
+ new.tap do |attribute|
7
+ attribute.name = name
8
+ attribute.format = options.delete(:format) || '%Y-%m-%d %H:%M'
9
+ attribute.lookup_key = options.delete(:from_within)
10
+ attribute.options = options.tap { |o| o.delete :as_a }
11
+ end
12
+ end
13
+
14
+ attr_accessor :name, :options, :lookup_key, :format
15
+
16
+ def is_an_attribute_of_type?(type)
17
+ type == :time || type == self.class
18
+ end
19
+
20
+ def value_for(pre_type_cast_value)
21
+ Time.strptime(pre_type_cast_value.to_s,format)
22
+ end
23
+
24
+ def set_value_on(object, options)
25
+ object.send accessor, value_from_hash(options[:from_value_in])
26
+ end
27
+
28
+ private
29
+ def accessor
30
+ :"#{name}="
31
+ end
32
+ def value_from_hash(hash)
33
+ value_for hash[ key_for(hash)]
34
+ end
35
+ def key_for(hash)
36
+ lookup_key || Build::Key.for(name, given: hash.keys)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,3 +1,3 @@
1
1
  module Setsumei
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ module Setsumei
4
+ module Describable
5
+ describe DateAttribute do
6
+ its(:name) { should == nil }
7
+
8
+ describe ".named(name)" do
9
+ let(:name) { :my_date_field }
10
+
11
+ subject { DateAttribute.named(name) }
12
+
13
+ it { should be_a DateAttribute }
14
+ its(:name) { should == name }
15
+ its(:format) { should == '%Y-%m-%d' }
16
+
17
+ context 'format specified' do
18
+ let(:format) { mock "format" }
19
+
20
+ subject { DateAttribute.named name, format: format }
21
+
22
+ its(:format) { should == format }
23
+ end
24
+
25
+ it_should_behave_like "it handles options properly"
26
+ end
27
+
28
+ describe "#value_for(pre_type_cast_value)" do
29
+ let(:attribute) { DateAttribute.new }
30
+
31
+ subject { attribute.value_for pre_type_cast_value }
32
+
33
+ context "where pre_type_cast_value is a string" do
34
+ let(:pre_type_cast_value) { "time" }
35
+ let(:formatted_value) { mock "formatted_value" }
36
+
37
+ it "should parse it into a time with format" do
38
+ Date.should_receive(:strptime).with(pre_type_cast_value.to_s,attribute.format).and_return(formatted_value)
39
+ subject.should == formatted_value
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#is_an_attribute_of_type?" do
45
+ let(:attribute) { DateAttribute.new }
46
+
47
+ subject { attribute.is_an_attribute_of_type? type }
48
+
49
+ context "where type is :date" do
50
+ let(:type) { :date }
51
+ it { should be_true }
52
+ end
53
+
54
+ context "where type is DateAttribute" do
55
+ let(:type) { DateAttribute }
56
+ it { should be_true }
57
+ end
58
+
59
+ context "where type is unknown" do
60
+ let(:type) { mock "an unknown type" }
61
+ it { should be_false }
62
+ end
63
+ end
64
+
65
+ describe "set_value_on object, from_value_in: hash" do
66
+ let(:hash) { Hash.new }
67
+ let(:key) { "key" }
68
+ let(:hash_keys) { mock "hash_keys" }
69
+ let(:value_in_hash) { mock "value_in_hash" }
70
+ let(:converted_value) { mock "converted_value" }
71
+
72
+ let(:object) { mock "object", :my_date_attribute= => nil }
73
+
74
+ let(:date_attribute) { DateAttribute.named :my_date_attribute }
75
+
76
+ before do
77
+ Build::Key.stub(:for).and_return(key)
78
+ hash[key] = value_in_hash
79
+ date_attribute.stub(:value_for).and_return(converted_value)
80
+ end
81
+
82
+ subject { date_attribute.set_value_on object, from_value_in: hash }
83
+
84
+ it "should detect the key it should use to retrieve the value from the hash" do
85
+ hash.should_receive(:keys).and_return(hash_keys)
86
+ Build::Key.should_receive(:for).with(:my_date_attribute, given: hash_keys ).and_return(key)
87
+ subject
88
+ end
89
+ it "should convert the value" do
90
+ date_attribute.should_receive(:value_for).with(value_in_hash).and_return(converted_value)
91
+ subject
92
+ end
93
+ it "should pass object a value to the attribute described by this class" do
94
+ object.should_receive(:my_date_attribute=).with(converted_value)
95
+ subject
96
+ end
97
+ it_should_behave_like "it handles lookup keys properly"
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ module Setsumei
4
+ module Describable
5
+ describe TimeAttribute do
6
+ its(:name) { should == nil }
7
+
8
+ describe ".named(name)" do
9
+ let(:name) { :my_time_field }
10
+
11
+ subject { TimeAttribute.named(name) }
12
+
13
+ it { should be_a TimeAttribute }
14
+ its(:name) { should == name }
15
+ its(:format) { should == '%Y-%m-%d %H:%M' }
16
+
17
+ context 'format specified' do
18
+ let(:format) { mock "format" }
19
+
20
+ subject { TimeAttribute.named name, format: format }
21
+
22
+ its(:format) { should == format }
23
+ end
24
+
25
+ it_should_behave_like "it handles options properly"
26
+ end
27
+
28
+ describe "#value_for(pre_type_cast_value)" do
29
+ let(:attribute) { TimeAttribute.new }
30
+
31
+ subject { attribute.value_for pre_type_cast_value }
32
+
33
+ context "where pre_type_cast_value is a string" do
34
+ let(:pre_type_cast_value) { "time" }
35
+ let(:formatted_value) { mock "formatted_value" }
36
+
37
+ it "should parse it into a time with format" do
38
+ Time.should_receive(:strptime).with(pre_type_cast_value,attribute.format).and_return(formatted_value)
39
+ subject.should == formatted_value
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#is_an_attribute_of_type?" do
45
+ let(:attribute) { TimeAttribute.new }
46
+
47
+ subject { attribute.is_an_attribute_of_type? type }
48
+
49
+ context "where type is :time" do
50
+ let(:type) { :time }
51
+ it { should be_true }
52
+ end
53
+
54
+ context "where type is TimeAttribute" do
55
+ let(:type) { TimeAttribute }
56
+ it { should be_true }
57
+ end
58
+
59
+ context "where type is unknown" do
60
+ let(:type) { mock "an unknown type" }
61
+ it { should be_false }
62
+ end
63
+ end
64
+
65
+ describe "set_value_on object, from_value_in: hash" do
66
+ let(:hash) { Hash.new }
67
+ let(:key) { "key" }
68
+ let(:hash_keys) { mock "hash_keys" }
69
+ let(:value_in_hash) { mock "value_in_hash" }
70
+ let(:converted_value) { mock "converted_value" }
71
+
72
+ let(:object) { mock "object", :my_time_attribute= => nil }
73
+
74
+ let(:time_attribute) { TimeAttribute.named :my_time_attribute }
75
+
76
+ before do
77
+ Build::Key.stub(:for).and_return(key)
78
+ hash[key] = value_in_hash
79
+ time_attribute.stub(:value_for).and_return(converted_value)
80
+ end
81
+
82
+ subject { time_attribute.set_value_on object, from_value_in: hash }
83
+
84
+ it "should detect the key it should use to retrieve the value from the hash" do
85
+ hash.should_receive(:keys).and_return(hash_keys)
86
+ Build::Key.should_receive(:for).with(:my_time_attribute, given: hash_keys ).and_return(key)
87
+ subject
88
+ end
89
+ it "should convert the value" do
90
+ time_attribute.should_receive(:value_for).with(value_in_hash).and_return(converted_value)
91
+ subject
92
+ end
93
+ it "should pass object a value to the attribute described by this class" do
94
+ object.should_receive(:my_time_attribute=).with(converted_value)
95
+ subject
96
+ end
97
+ it_should_behave_like "it handles lookup keys properly"
98
+ end
99
+ end
100
+ end
101
+ end
@@ -43,10 +43,12 @@ module Setsumei
43
43
  context "where setting a specific type" do
44
44
  subject { klass }
45
45
 
46
- it_should_behave_like "it creates an attribute of type", :boolean, creating_a: Describable::BooleanAttribute
47
- it_should_behave_like "it creates an attribute of type", :string, creating_a: Describable::StringAttribute
48
- it_should_behave_like "it creates an attribute of type", :float, creating_a: Describable::FloatAttribute
49
- it_should_behave_like "it creates an attribute of type", :int, creating_a: Describable::IntAttribute
46
+ it_should_behave_like "it creates an attribute of type", :boolean, creating_a: Describable::BooleanAttribute
47
+ it_should_behave_like "it creates an attribute of type", :string, creating_a: Describable::StringAttribute
48
+ it_should_behave_like "it creates an attribute of type", :float, creating_a: Describable::FloatAttribute
49
+ it_should_behave_like "it creates an attribute of type", :int, creating_a: Describable::IntAttribute
50
+ it_should_behave_like "it creates an attribute of type", :date, creating_a: Describable::DateAttribute
51
+ it_should_behave_like "it creates an attribute of type", :time, creating_a: Describable::TimeAttribute
50
52
 
51
53
  it_should_behave_like "it creates an attribute of type", Class.new, creating_a: Describable::ObjectAttribute
52
54
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: setsumei
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.7
5
+ version: 0.0.8
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jon Rowe
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-10 00:00:00 +01:00
13
+ date: 2011-06-13 00:00:00 +01:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -78,20 +78,24 @@ files:
78
78
  - lib/setsumei/describable.rb
79
79
  - lib/setsumei/describable/boolean_attribute.rb
80
80
  - lib/setsumei/describable/collection.rb
81
+ - lib/setsumei/describable/date_attribute.rb
81
82
  - lib/setsumei/describable/float_attribute.rb
82
83
  - lib/setsumei/describable/int_attribute.rb
83
84
  - lib/setsumei/describable/object_attribute.rb
84
85
  - lib/setsumei/describable/string_attribute.rb
86
+ - lib/setsumei/describable/time_attribute.rb
85
87
  - lib/setsumei/version.rb
86
88
  - setsumei.gemspec
87
89
  - spec/setsumei/build/key_spec.rb
88
90
  - spec/setsumei/build_spec.rb
89
91
  - spec/setsumei/describable/boolean_attribute_spec.rb
90
92
  - spec/setsumei/describable/collection_spec.rb
93
+ - spec/setsumei/describable/date_attribute_spec.rb
91
94
  - spec/setsumei/describable/float_attribute_spec.rb
92
95
  - spec/setsumei/describable/int_attribute_spec.rb
93
96
  - spec/setsumei/describable/object_attribute_spec.rb
94
97
  - spec/setsumei/describable/string_attribute_spec.rb
98
+ - spec/setsumei/describable/time_attribute_spec.rb
95
99
  - spec/setsumei/describable_spec.rb
96
100
  - spec/spec_helper.rb
97
101
  - spec/support/be_an_attribute_of_type_matcher.rb
@@ -131,10 +135,12 @@ test_files:
131
135
  - spec/setsumei/build_spec.rb
132
136
  - spec/setsumei/describable/boolean_attribute_spec.rb
133
137
  - spec/setsumei/describable/collection_spec.rb
138
+ - spec/setsumei/describable/date_attribute_spec.rb
134
139
  - spec/setsumei/describable/float_attribute_spec.rb
135
140
  - spec/setsumei/describable/int_attribute_spec.rb
136
141
  - spec/setsumei/describable/object_attribute_spec.rb
137
142
  - spec/setsumei/describable/string_attribute_spec.rb
143
+ - spec/setsumei/describable/time_attribute_spec.rb
138
144
  - spec/setsumei/describable_spec.rb
139
145
  - spec/spec_helper.rb
140
146
  - spec/support/be_an_attribute_of_type_matcher.rb