setsumei 0.0.10 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -0
- data/.travis.yml +7 -0
- data/README.md +1 -0
- data/Rakefile +7 -0
- data/lib/setsumei/describable.rb +17 -18
- data/lib/setsumei/describable/attribute.rb +43 -0
- data/lib/setsumei/describable/boolean_attribute.rb +4 -29
- data/lib/setsumei/describable/date_time_attribute.rb +21 -0
- data/lib/setsumei/describable/float_attribute.rb +4 -29
- data/lib/setsumei/describable/int_attribute.rb +4 -28
- data/lib/setsumei/describable/object_attribute.rb +9 -35
- data/lib/setsumei/describable/string_attribute.rb +4 -28
- data/lib/setsumei/version.rb +1 -1
- data/setsumei.gemspec +3 -2
- data/spec/setsumei/describable/attribute_spec.rb +94 -0
- data/spec/setsumei/describable/boolean_attribute_spec.rb +13 -71
- data/spec/setsumei/describable/date_attribute_spec.rb +18 -79
- data/spec/setsumei/describable/float_attribute_spec.rb +8 -69
- data/spec/setsumei/describable/int_attribute_spec.rb +10 -69
- data/spec/setsumei/describable/object_attribute_spec.rb +20 -75
- data/spec/setsumei/describable/string_attribute_spec.rb +7 -66
- data/spec/setsumei/describable/time_attribute_spec.rb +20 -78
- data/spec/setsumei/describable_spec.rb +2 -2
- data/spec/spec_helper.rb +0 -1
- data/spec/support/shared_examples/attribute_options.rb +4 -4
- data/spec/support/shared_examples/attribute_type_creation.rb +1 -1
- metadata +65 -35
- metadata.gz.sig +3 -0
- data/lib/setsumei/describable/date_attribute.rb +0 -40
- data/lib/setsumei/describable/time_attribute.rb +0 -40
- data/spec/support/shared_examples/attribute_lookup_key_support.rb +0 -15
checksums.yaml
ADDED
@@ -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
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
@@ -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
|
data/.travis.yml
ADDED
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
data/lib/setsumei/describable.rb
CHANGED
@@ -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/
|
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
|
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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
6
|
-
|
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
|
-
|
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
|
6
|
-
|
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
|
-
|
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
|
20
|
-
|
5
|
+
def == other
|
6
|
+
:int == other || IntAttribute == other
|
21
7
|
end
|
22
8
|
|
23
|
-
def
|
24
|
-
|
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
|
6
|
-
|
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
|
-
|
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
|
14
|
+
def cast data
|
23
15
|
return nil if data.nil? || data.empty?
|
24
16
|
|
25
17
|
begin
|
26
|
-
|
18
|
+
klass.create_from data
|
27
19
|
rescue NoMethodError
|
28
|
-
Build.a
|
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
|
20
|
-
|
5
|
+
def == other
|
6
|
+
:string == other || StringAttribute == other
|
21
7
|
end
|
22
8
|
|
23
|
-
def
|
24
|
-
|
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
|
data/lib/setsumei/version.rb
CHANGED
data/setsumei.gemspec
CHANGED
@@ -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
|
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
|