structure 0.23.1 → 0.24.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/structure.rb +22 -13
- data/lib/structure/version.rb +1 -1
- data/test/structure_with_fields_test.rb +14 -1
- metadata +3 -8
data/lib/structure.rb
CHANGED
@@ -4,8 +4,8 @@ rescue NameError
|
|
4
4
|
require 'json'
|
5
5
|
end
|
6
6
|
|
7
|
-
# Structure is a key/value container. On the most basic level, it
|
8
|
-
#
|
7
|
+
# Structure is a key/value container. On the most basic level, it mirrors the
|
8
|
+
# functionality of OpenStruct:
|
9
9
|
#
|
10
10
|
# require 'structure'
|
11
11
|
#
|
@@ -42,7 +42,7 @@ end
|
|
42
42
|
#
|
43
43
|
# class Price < Structure
|
44
44
|
# field :cents, Integer
|
45
|
-
# field :currency, :default => "USD"
|
45
|
+
# field :currency, String, :default => "USD"
|
46
46
|
# end
|
47
47
|
#
|
48
48
|
# hash = { "cents" => "100" }
|
@@ -51,11 +51,12 @@ end
|
|
51
51
|
# puts price.cents # -> 100
|
52
52
|
# puts price.currency # -> "USD"
|
53
53
|
#
|
54
|
-
# Alternatively, define a proc to cast or otherwise manipulate
|
55
|
-
#
|
54
|
+
# Alternatively, define a proc to cast or otherwise manipulate values and
|
55
|
+
# assign defaults:
|
56
56
|
#
|
57
57
|
# class Product < Structure
|
58
58
|
# field :sku, lambda(&:upcase)
|
59
|
+
# field :created_at, String, :default => lambda { Time.now.to_s }
|
59
60
|
# end
|
60
61
|
#
|
61
62
|
# product = Product.new(:sku => 'foo-bar')
|
@@ -96,13 +97,20 @@ class Structure
|
|
96
97
|
:default => default }
|
97
98
|
end
|
98
99
|
|
99
|
-
|
100
|
-
|
100
|
+
alias key field
|
101
|
+
|
102
|
+
# Syntactic sugar to create a typed field that defaults to an empty array.
|
101
103
|
# @param key the name of the field
|
102
104
|
def many(key)
|
103
105
|
field(key, Array, :default => [])
|
104
106
|
end
|
105
107
|
|
108
|
+
# Syntactic sugar to create a field that stands in for another structure.
|
109
|
+
# @param key the name of the field
|
110
|
+
def one(key)
|
111
|
+
field(key, lambda { |v| v.is_a?(Structure) ? v : Structure.new(v) })
|
112
|
+
end
|
113
|
+
|
106
114
|
private
|
107
115
|
|
108
116
|
def inherited(child)
|
@@ -115,11 +123,13 @@ class Structure
|
|
115
123
|
# Creates a new structure.
|
116
124
|
# @param [Hash] hsh an optional hash to populate fields
|
117
125
|
def initialize(hsh = {})
|
118
|
-
# It may have improved performance if I had defined these methods
|
119
|
-
# on the class level, but I decided to privilege consistency here.
|
120
|
-
# Who wouldn't?
|
121
126
|
@table = blueprint.inject({}) do |a, (k, v)|
|
122
|
-
default = v[:default].
|
127
|
+
default = if v[:default].is_a? Proc
|
128
|
+
v[:default].call
|
129
|
+
else
|
130
|
+
v[:default].dup rescue v[:default]
|
131
|
+
end
|
132
|
+
|
123
133
|
a.merge new_field(k, v[:type]) => default
|
124
134
|
end
|
125
135
|
|
@@ -147,8 +157,7 @@ class Structure
|
|
147
157
|
end
|
148
158
|
|
149
159
|
# Provides marshalling support for use by the Marshal library.
|
150
|
-
# @param [Hash] hsh a hash of keys and values to populate the
|
151
|
-
# structure
|
160
|
+
# @param [Hash] hsh a hash of keys and values to populate the structure
|
152
161
|
def marshal_load(hsh)
|
153
162
|
hsh.each do |k, v|
|
154
163
|
self.send("#{new_field(k)}=", v)
|
data/lib/structure/version.rb
CHANGED
@@ -5,8 +5,10 @@ class Product < Structure
|
|
5
5
|
field :sku, lambda(&:upcase)
|
6
6
|
field :cents, Integer
|
7
7
|
field :currency, String, :default => 'USD'
|
8
|
-
|
8
|
+
key :in_stock, :default => true
|
9
|
+
field :created_on, :default => lambda { Date.today }
|
9
10
|
many :related
|
11
|
+
one :manufacturer
|
10
12
|
end
|
11
13
|
|
12
14
|
class Foo < Structure
|
@@ -46,6 +48,7 @@ class TestStructureWithFields < MiniTest::Unit::TestCase
|
|
46
48
|
assert_equal 'USD', @product.currency
|
47
49
|
assert_equal true, @product.in_stock
|
48
50
|
assert_equal [], @product.related
|
51
|
+
assert_kind_of Date, @product.created_on
|
49
52
|
end
|
50
53
|
|
51
54
|
def test_recursive_hashes
|
@@ -64,4 +67,14 @@ class TestStructureWithFields < MiniTest::Unit::TestCase
|
|
64
67
|
assert_equal [related], @product.related
|
65
68
|
assert_equal [], @product.related.first.related
|
66
69
|
end
|
70
|
+
|
71
|
+
def test_one_to_one
|
72
|
+
hsh = { :name => 'Manufacturer' }
|
73
|
+
|
74
|
+
@product.manufacturer = Structure.new(hsh)
|
75
|
+
assert_equal 'Manufacturer', @product.manufacturer.name
|
76
|
+
|
77
|
+
@product.manufacturer = hsh
|
78
|
+
assert_equal 'Manufacturer', @product.manufacturer.name
|
79
|
+
end
|
67
80
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: structure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-16 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Structure is a key/value container.
|
15
15
|
email:
|
@@ -44,18 +44,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
44
|
- - ! '>='
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
|
-
segments:
|
48
|
-
- 0
|
49
|
-
hash: 2719962180742855248
|
50
47
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
48
|
none: false
|
52
49
|
requirements:
|
53
50
|
- - ! '>='
|
54
51
|
- !ruby/object:Gem::Version
|
55
52
|
version: '0'
|
56
|
-
segments:
|
57
|
-
- 0
|
58
|
-
hash: 2719962180742855248
|
59
53
|
requirements: []
|
60
54
|
rubyforge_project: structure
|
61
55
|
rubygems_version: 1.8.11
|
@@ -66,3 +60,4 @@ test_files:
|
|
66
60
|
- test/helper.rb
|
67
61
|
- test/structure_test.rb
|
68
62
|
- test/structure_with_fields_test.rb
|
63
|
+
has_rdoc:
|