setsumei 0.0.7 → 0.0.8

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.
@@ -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