setsumei 0.0.10 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -0
  4. data/.travis.yml +7 -0
  5. data/README.md +1 -0
  6. data/Rakefile +7 -0
  7. data/lib/setsumei/describable.rb +17 -18
  8. data/lib/setsumei/describable/attribute.rb +43 -0
  9. data/lib/setsumei/describable/boolean_attribute.rb +4 -29
  10. data/lib/setsumei/describable/date_time_attribute.rb +21 -0
  11. data/lib/setsumei/describable/float_attribute.rb +4 -29
  12. data/lib/setsumei/describable/int_attribute.rb +4 -28
  13. data/lib/setsumei/describable/object_attribute.rb +9 -35
  14. data/lib/setsumei/describable/string_attribute.rb +4 -28
  15. data/lib/setsumei/version.rb +1 -1
  16. data/setsumei.gemspec +3 -2
  17. data/spec/setsumei/describable/attribute_spec.rb +94 -0
  18. data/spec/setsumei/describable/boolean_attribute_spec.rb +13 -71
  19. data/spec/setsumei/describable/date_attribute_spec.rb +18 -79
  20. data/spec/setsumei/describable/float_attribute_spec.rb +8 -69
  21. data/spec/setsumei/describable/int_attribute_spec.rb +10 -69
  22. data/spec/setsumei/describable/object_attribute_spec.rb +20 -75
  23. data/spec/setsumei/describable/string_attribute_spec.rb +7 -66
  24. data/spec/setsumei/describable/time_attribute_spec.rb +20 -78
  25. data/spec/setsumei/describable_spec.rb +2 -2
  26. data/spec/spec_helper.rb +0 -1
  27. data/spec/support/shared_examples/attribute_options.rb +4 -4
  28. data/spec/support/shared_examples/attribute_type_creation.rb +1 -1
  29. metadata +65 -35
  30. metadata.gz.sig +3 -0
  31. data/lib/setsumei/describable/date_attribute.rb +0 -40
  32. data/lib/setsumei/describable/time_attribute.rb +0 -40
  33. data/spec/support/shared_examples/attribute_lookup_key_support.rb +0 -15
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3ed66d6642b9aa0f6e115bae45ee429c0112e70f
4
+ data.tar.gz: d927bc2bb3d1df4a38fed82b9c65d60a18d6fdd7
5
+ SHA512:
6
+ metadata.gz: 17f822edef6b4b2a23a57d6b74b5ed3834d0085842231998df12e8fce800ca0569f247ad307ce230b1c2bfc8e44e3db7f95f26cabc70e5a766748181187319e6
7
+ data.tar.gz: 1db588dd87cd2362cc1742c1fd7c8b6fccf32f1abd60028754c672bf8c3f4886e5b73875047e943c30aa46b2e29ebe4a671bb995bc92aafea058865e7397b24a
Binary file
@@ -0,0 +1 @@
1
+ �e(՝I�C)�X���I�<�]}�d�-!Ar�\��Mk�=(�{�f^��4F[�:d���ez�����r��#Z������ ��&@n�1�I���V_�����&�k?尓�(ݿ��1�ϫՊt����˩k���ߵ�N�AXc��i���������Y����q<v�s@������ �m�r6��b9zt�_8;���t��蕝�7�����G�*��mPs}2ô7
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - 2.0.0
6
+ - jruby-19mode
7
+ - rbx-19mode
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  Setsumei
2
2
  --------
3
+ [![Build Status](https://secure.travis-ci.org/JonRowe/setsumei.png)](http://travis-ci.org/JonRowe/setsumei) [![Code Climate](https://codeclimate.com/github/JonRowe/setsumei.png)](https://codeclimate.com/github/JonRowe/setsumei)
3
4
 
4
5
  Api description tool to build ruby DSL's from JSON data.
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new :spec
9
+ task :default => [:spec]
@@ -1,10 +1,10 @@
1
+ require 'setsumei/describable/attribute'
1
2
  require 'setsumei/describable/boolean_attribute'
2
3
  require 'setsumei/describable/string_attribute'
3
4
  require 'setsumei/describable/float_attribute'
4
5
  require 'setsumei/describable/int_attribute'
5
6
  require 'setsumei/describable/object_attribute'
6
- require 'setsumei/describable/time_attribute'
7
- require 'setsumei/describable/date_attribute'
7
+ require 'setsumei/describable/date_time_attribute'
8
8
  require 'setsumei/describable/collection'
9
9
 
10
10
  module Setsumei
@@ -21,7 +21,7 @@ module Setsumei
21
21
  end
22
22
 
23
23
  def define field_name, options = {}
24
- _defined_attributes[field_name] = attribute_type(options[:as_a]).named field_name, options
24
+ _defined_attributes[field_name] = Attribute.new field_name, attribute_type(options), options
25
25
  attr_accessor field_name
26
26
  end
27
27
 
@@ -66,21 +66,20 @@ module Setsumei
66
66
  def _defined_attributes
67
67
  (@_defined_attributes ||= {})
68
68
  end
69
- def attribute_type(type)
70
- case type
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
78
- else
79
- object_attribute_if_a_class(type) or raise(ArgumentError)
80
- end
81
- end
82
- def object_attribute_if_a_class(type)
83
- (type.is_a?(Class) && ObjectAttribute)
69
+
70
+ def attribute_type(options = {})
71
+ case options.fetch(:as_a,:string)
72
+ when :boolean then BooleanAttribute.new
73
+ when :string then StringAttribute.new
74
+ when nil then StringAttribute.new
75
+ when :float then FloatAttribute.new
76
+ when :int then IntAttribute.new
77
+ when :date then DateTimeAttribute.new(:date, options[:format], Date)
78
+ when :time then DateTimeAttribute.new(:time, options[:format], Time)
79
+ when Class then ObjectAttribute.new(options[:as_a])
80
+ else
81
+ raise ArgumentError
82
+ end
84
83
  end
85
84
  end
86
85
  end
@@ -0,0 +1,43 @@
1
+ module Setsumei
2
+ module Describable
3
+ class Attribute
4
+
5
+ def initialize name, type, options = {}
6
+ self.name = name
7
+ self.type = type
8
+ self.lookup_key = options.delete(:from_within)
9
+ self.options = options.tap { |o| o.delete :as_a }
10
+ end
11
+
12
+ attr_accessor :name, :options, :lookup_key, :type, :klass
13
+
14
+ def is_an_attribute_of_type?(other)
15
+ type == other
16
+ end
17
+ alias :is_a? :is_an_attribute_of_type?
18
+ alias :kind_of? :is_an_attribute_of_type?
19
+
20
+ def value_for(pre_type_cast_value)
21
+ type.cast pre_type_cast_value
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
+
33
+ def value_from_hash(hash)
34
+ value_for hash[ key_for(hash)]
35
+ end
36
+
37
+ def key_for(hash)
38
+ lookup_key || Build::Key.for(name, given: hash.keys)
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -2,39 +2,14 @@ module Setsumei
2
2
  module Describable
3
3
  class BooleanAttribute
4
4
 
5
- def BooleanAttribute.named(name, options = {})
6
- options = options.dup
7
- new.tap do |attribute|
8
- attribute.name = name
9
- attribute.lookup_key = options.delete(:from_within)
10
- attribute.options = options.tap { |o| o.delete :as_a }
11
- end
5
+ def == other
6
+ :boolean == other || BooleanAttribute == other
12
7
  end
13
8
 
14
- attr_accessor :name, :options, :lookup_key
15
-
16
- def is_an_attribute_of_type?(type)
17
- type == :boolean || type == self.class
18
- end
19
-
20
- def value_for(pre_type_cast_value)
21
- pre_type_cast_value.to_s.downcase == "true" || pre_type_cast_value.to_s == "1"
22
- end
23
-
24
- def set_value_on(object, options)
25
- object.send accessor, value_from_hash(options[:from_value_in])
9
+ def cast value
10
+ value.to_s.downcase == "true" || value.to_s == "1"
26
11
  end
27
12
 
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
13
  end
39
14
  end
40
15
  end
@@ -0,0 +1,21 @@
1
+ module Setsumei
2
+ module Describable
3
+ class DateTimeAttribute
4
+
5
+ def initialize type, format, parser
6
+ @type, @parser = type, parser
7
+ @format = format || '%Y-%m-%d %H:%M'
8
+ end
9
+ attr_reader :format, :type, :parser
10
+
11
+ def == other
12
+ type == other || self.class == other
13
+ end
14
+
15
+ def cast value
16
+ parser.strptime value, format
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -2,39 +2,14 @@ module Setsumei
2
2
  module Describable
3
3
  class FloatAttribute
4
4
 
5
- def FloatAttribute.named(name, options = {})
6
- options = options.dup
7
- new.tap do |attribute|
8
- attribute.name = name
9
- attribute.lookup_key = options.delete(:from_within)
10
- attribute.options = options.tap { |o| o.delete :as_a }
11
- end
5
+ def == other
6
+ :float == other || FloatAttribute == other
12
7
  end
13
8
 
14
- attr_accessor :name, :options, :lookup_key
15
-
16
- def is_an_attribute_of_type?(type)
17
- type == :float || type == self.class
18
- end
19
-
20
- def value_for(pre_type_cast_value)
21
- pre_type_cast_value.to_f
22
- end
23
-
24
- def set_value_on(object, options)
25
- object.send accessor, value_from_hash(options[:from_value_in])
9
+ def cast value
10
+ value.to_f
26
11
  end
27
12
 
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
13
  end
39
14
  end
40
15
  end
@@ -1,39 +1,15 @@
1
1
  module Setsumei
2
2
  module Describable
3
3
  class IntAttribute
4
- def IntAttribute.named(name, options = {})
5
- options = options.dup
6
- new.tap do |attribute|
7
- attribute.name = name
8
- attribute.lookup_key = options.delete(:from_within)
9
- attribute.options = options.tap { |o| o.delete :as_a }
10
- end
11
- end
12
-
13
- attr_accessor :name, :options, :lookup_key
14
-
15
- def is_an_attribute_of_type?(type)
16
- type == :int || type == self.class
17
- end
18
4
 
19
- def value_for(pre_type_cast_value)
20
- pre_type_cast_value.to_f.round
5
+ def == other
6
+ :int == other || IntAttribute == other
21
7
  end
22
8
 
23
- def set_value_on(object, options)
24
- object.send accessor, value_from_hash(options[:from_value_in])
9
+ def cast value
10
+ value.to_f.round
25
11
  end
26
12
 
27
- private
28
- def accessor
29
- :"#{name}="
30
- end
31
- def value_from_hash(hash)
32
- value_for hash[ key_for(hash)]
33
- end
34
- def key_for(hash)
35
- lookup_key || Build::Key.for(name, given: hash.keys)
36
- end
37
13
  end
38
14
  end
39
15
  end
@@ -1,52 +1,26 @@
1
1
  module Setsumei
2
2
  module Describable
3
- class ObjectAttribute
3
+ class ObjectAttribute < Attribute
4
4
 
5
- def ObjectAttribute.named(name,options = {})
6
- options = options.dup
7
- raise ArgumentError.new("you must specify what the object is") unless options.has_key? :as_a
8
- new.tap do |attribute|
9
- attribute.name = name
10
- attribute.klass = options.delete(:as_a)
11
- attribute.lookup_key = options.delete(:from_within)
12
- attribute.options = options
13
- end
5
+ def initialize type = nil
6
+ @klass = type || Object
14
7
  end
8
+ attr_reader :klass
15
9
 
16
- attr_accessor :name, :klass, :options, :lookup_key
17
-
18
- def initialize
19
- self.klass = Object
10
+ def == other
11
+ :object == other || ObjectAttribute == other || klass == other
20
12
  end
21
13
 
22
- def value_for(data)
14
+ def cast data
23
15
  return nil if data.nil? || data.empty?
24
16
 
25
17
  begin
26
- self.klass.create_from data
18
+ klass.create_from data
27
19
  rescue NoMethodError
28
- Build.a self.klass, from: data
20
+ Build.a klass, from: data
29
21
  end
30
22
  end
31
23
 
32
- def is_an_attribute_of_type?(type)
33
- type == :object || type == self.class || type == self.klass
34
- end
35
-
36
- def set_value_on(object, options)
37
- object.send accessor, value_from_hash(options[:from_value_in])
38
- end
39
-
40
- private
41
- def accessor
42
- :"#{name}="
43
- end
44
- def value_from_hash(hash)
45
- value_for hash[ key_for(hash)]
46
- end
47
- def key_for(hash)
48
- lookup_key || Build::Key.for(name, given: hash.keys)
49
- end
50
24
  end
51
25
  end
52
26
  end
@@ -1,39 +1,15 @@
1
1
  module Setsumei
2
2
  module Describable
3
3
  class StringAttribute
4
- def StringAttribute.named(name,options = {})
5
- options = options.dup
6
- new.tap do |attribute|
7
- attribute.name = name
8
- attribute.lookup_key = options.delete(:from_within)
9
- attribute.options = options.tap { |o| o.delete :as_a }
10
- end
11
- end
12
-
13
- attr_accessor :name, :options, :lookup_key
14
-
15
- def is_an_attribute_of_type?(type)
16
- type == :string || type == self.class
17
- end
18
4
 
19
- def value_for(pre_type_cast_value)
20
- pre_type_cast_value.to_s
5
+ def == other
6
+ :string == other || StringAttribute == other
21
7
  end
22
8
 
23
- def set_value_on(object, options)
24
- object.send accessor, value_from_hash(options[:from_value_in])
9
+ def cast value
10
+ value.to_s
25
11
  end
26
12
 
27
- private
28
- def accessor
29
- :"#{name}="
30
- end
31
- def value_from_hash(hash)
32
- value_for hash[ key_for(hash)]
33
- end
34
- def key_for(hash)
35
- lookup_key || Build::Key.for(name, given: hash.keys)
36
- end
37
13
  end
38
14
  end
39
15
  end
@@ -1,3 +1,3 @@
1
1
  module Setsumei
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.12"
3
3
  end
@@ -17,8 +17,9 @@ Gem::Specification.new do |s|
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
19
 
20
- s.add_runtime_dependency 'json'
20
+ s.add_runtime_dependency 'json'
21
+
22
+ s.add_development_dependency 'rake'
21
23
  s.add_development_dependency 'rspec'
22
24
  s.add_development_dependency 'autotest-standalone'
23
- s.add_development_dependency 'ruby-debug19'
24
25
  end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ module Setsumei
4
+ module Describable
5
+ describe Attribute do
6
+
7
+ let(:attribute) { Attribute.new :name, type }
8
+
9
+ describe '#initialize name, type' do
10
+ let(:type) { double }
11
+ subject { attribute }
12
+
13
+ its(:name) { should == :name }
14
+ its(:type) { should == type }
15
+ end
16
+
17
+ describe "#value_for(value)" do
18
+ let(:type) { double "type", cast: cast }
19
+ let(:value) { double "value" }
20
+ let(:cast) { double "cast" }
21
+
22
+ it 'will cast value to type' do
23
+ type.should_receive(:cast).with(value)
24
+ attribute.value_for value
25
+ end
26
+ it 'will return the cast value' do
27
+ attribute.value_for(value).should == cast
28
+ end
29
+ end
30
+
31
+ %w[is_an_attribute_of_type? is_a? kind_of?].each do |meth|
32
+ describe "##{meth}" do
33
+ let(:type) { double "type", :== => result }
34
+ let(:other) { double "value" }
35
+ let(:result) { double "result" }
36
+
37
+ it 'compares using type' do
38
+ type.should_receive(:==).with(other)
39
+ attribute.send meth, other
40
+ end
41
+ it 'returns the value' do
42
+ attribute.send(meth, other).should eq result
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "set_value_on object, from_value_in: hash" do
48
+ let(:hash) { Hash.new }
49
+ let(:key) { "key" }
50
+ let(:hash_keys) { mock "hash_keys" }
51
+ let(:value_in_hash) { mock "value_in_hash" }
52
+
53
+ let(:object) { mock "object", :name= => nil }
54
+
55
+ let(:converted_value) { mock "converted_value" }
56
+ let(:type) { double "type", cast: converted_value }
57
+
58
+ before do
59
+ Build::Key.stub(:for).and_return(key)
60
+ hash[key] = value_in_hash
61
+ end
62
+
63
+ subject { attribute.set_value_on object, from_value_in: hash }
64
+
65
+ it "should detect the key it should use to retrieve the value from the hash" do
66
+ hash.should_receive(:keys).and_return(hash_keys)
67
+ Build::Key.should_receive(:for).with(:name, given: hash_keys ).and_return(key)
68
+ subject
69
+ end
70
+ it "should convert the value" do
71
+ attribute.should_receive(:value_for).with(value_in_hash).and_return(converted_value)
72
+ subject
73
+ end
74
+ it "should pass object a value to the attribute described by this class" do
75
+ object.should_receive(:name=).with(converted_value)
76
+ subject
77
+ end
78
+
79
+ context "where a specific key has been specified" do
80
+ before do
81
+ hash["MySpecialKey"] = hash.delete key
82
+ attribute.lookup_key = "MySpecialKey"
83
+ end
84
+
85
+ it "should use this key for the hash lookup instead" do
86
+ Setsumei::Build::Key.should_not_receive(:for)
87
+ type.should_receive(:cast).with(value_in_hash).and_return(converted_value)
88
+ subject
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end