setsumei 0.0.10 → 0.0.12

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