structure 0.12.1 → 0.12.2

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.
data/Rakefile CHANGED
@@ -3,10 +3,8 @@ require 'rspec/core/rake_task'
3
3
 
4
4
  Bundler::GemHelper.install_tasks
5
5
 
6
- desc 'Run all specs in spec directory'
7
6
  RSpec::Core::RakeTask.new(:spec) do |t|
8
7
  t.pattern = "spec/**/*_spec.rb"
9
- t.rspec_opts = %w(-fd -c)
10
8
  end
11
9
 
12
10
  task :default => [:spec]
data/lib/structure.rb CHANGED
@@ -1,3 +1,9 @@
1
+ begin
2
+ ::JSON::JSON_LOADED
3
+ rescue NameError
4
+ require 'json'
5
+ end
6
+
1
7
  # Ruby doesn't have a Boolean class, so let's feign one.
2
8
  unless Object.const_defined?(:Boolean)
3
9
  module Boolean; end
@@ -5,7 +11,7 @@ unless Object.const_defined?(:Boolean)
5
11
  class FalseClass; include Boolean; end
6
12
  end
7
13
 
8
- # A Struct-like data container.
14
+ # A key/value container for modeling ephemeral data.
9
15
  class Structure
10
16
  include Enumerable
11
17
 
@@ -23,6 +29,11 @@ class Structure
23
29
  key name, Structure
24
30
  end
25
31
 
32
+ def json_create(object)
33
+ object.delete('json_class')
34
+ new(object)
35
+ end
36
+
26
37
  # Defines an attribute key.
27
38
  #
28
39
  # Takes a name, an optional type, and an optional hash of options.
@@ -114,13 +125,36 @@ class Structure
114
125
  #
115
126
  # Optionally, seeds the structure with a hash of attributes.
116
127
  def initialize(seed = {})
117
- initialize_attributes
128
+ @attributes = {}
129
+ self.class.default_attributes.each do |key, value|
130
+ @attributes[key] = value.is_a?(Array) ? value.dup : value
131
+ end
132
+
118
133
  seed.each { |key, value| self.send("#{key}=", value) }
119
134
  end
120
135
 
121
136
  # A hash of attributes.
122
137
  attr_reader :attributes
123
138
 
139
+ def as_json(options = nil)
140
+ # create a subset of the attributes by applying :only or :except
141
+ subset = if options
142
+ if attrs = options[:only]
143
+ @attributes.slice(*Array.wrap(attrs))
144
+ elsif attrs = options[:except]
145
+ @attributes.except(*Array.wrap(attrs))
146
+ else
147
+ @attributes.dup
148
+ end
149
+ else
150
+ @attributes.dup
151
+ end
152
+
153
+ klass = self.class.name
154
+ { JSON.create_id => klass }.
155
+ merge(subset)
156
+ end
157
+
124
158
  def each(&block)
125
159
  @attributes.each { |value| block.call(value) }
126
160
  end
@@ -130,24 +164,22 @@ class Structure
130
164
  @attributes.keys
131
165
  end
132
166
 
167
+ def to_json(*args)
168
+ klass = self.class.name
169
+ { JSON.create_id => klass }.
170
+ merge(@attributes).
171
+ to_json(*args)
172
+ end
173
+
133
174
  # Returns an array populated with the attribute values.
134
175
  def values
135
176
  @attributes.values
136
177
  end
137
178
 
138
179
  # Compares this object with another object for equality. A Structure is equal
139
- # to the other object when latter is also a Structure and the two objects'
140
- # attributes are equal.
180
+ # to the other object when latter is of the same class and the two objects'
181
+ # attributes are the same.
141
182
  def ==(other)
142
- other.is_a?(Structure) && @attributes == other.attributes
143
- end
144
-
145
- private
146
-
147
- def initialize_attributes
148
- @attributes = {}
149
- self.class.default_attributes.each do |key, value|
150
- @attributes[key] = value.is_a?(Array) ? value.dup : value
151
- end
183
+ other.is_a?(self.class) && @attributes == other.attributes
152
184
  end
153
185
  end
@@ -1,3 +1,3 @@
1
1
  class Structure
2
- VERSION = '0.12.1'
2
+ VERSION = '0.12.2'
3
3
  end
@@ -0,0 +1,7 @@
1
+ ---
2
+ - id: 1
3
+ name: New York
4
+ neighborhoods:
5
+ - name: Manhattan
6
+ - name: Brooklyn
7
+ - name: Queens
data/spec/models/city.rb CHANGED
@@ -5,5 +5,10 @@ class City < Structure
5
5
 
6
6
  set_data_path File.expand_path("../../fixtures/cities.yml", __FILE__)
7
7
 
8
+ key :name
9
+ embeds_many :neighborhoods
10
+ end
11
+
12
+ class Neighborhood < Structure
8
13
  key :name
9
14
  end
@@ -26,10 +26,6 @@ describe Structure do
26
26
  let(:json) { '{"json_class":"Person","name":"Joe","age":null,"friends":[]}' }
27
27
 
28
28
  context "without Active Support" do
29
- before(:all) do
30
- require 'structure/json'
31
- end
32
-
33
29
  it_behaves_like "a JSON interface"
34
30
  end
35
31
 
@@ -37,7 +33,6 @@ describe Structure do
37
33
  before(:all) do
38
34
  require 'active_support/ordered_hash'
39
35
  require 'active_support/json'
40
- load 'structure/json.rb'
41
36
  end
42
37
 
43
38
  after(:all) do
@@ -2,6 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  class Structure
4
4
  describe "A static structure" do
5
+ def replace_fixture(new_path)
6
+ City.instance_variable_set(:@all, nil)
7
+ fixture = File.expand_path("../../fixtures/#{new_path}", __FILE__)
8
+ City.set_data_path(fixture)
9
+ end
10
+
5
11
  it "is enumerable" do
6
12
  City.should be_an Enumerable
7
13
  end
@@ -29,11 +35,14 @@ class Structure
29
35
  end
30
36
  end
31
37
 
32
- context "when sourced data does not include ids" do
38
+ context "when sourcing data without ids" do
33
39
  before(:all) do
34
- City.instance_variable_set(:@all, nil)
35
- fixture = File.expand_path("../../fixtures/cities_without_id.yml", __FILE__)
36
- City.set_data_path(fixture)
40
+ @old_path = City.instance_variable_get(:@data_path)
41
+ replace_fixture("cities_without_id.yml")
42
+ end
43
+
44
+ after(:all) do
45
+ replace_fixture(@old_path)
37
46
  end
38
47
 
39
48
  it "should auto-increment the ids of loaded records" do
@@ -55,5 +64,22 @@ class Structure
55
64
  end
56
65
  end
57
66
  end
67
+
68
+ context "when sourcing nested models" do
69
+ before(:all) do
70
+ @old_path = City.instance_variable_get(:@data_path)
71
+ replace_fixture("cities_with_neighborhoods.yml")
72
+ end
73
+
74
+ after(:all) do
75
+ replace_fixture(@old_path)
76
+ end
77
+
78
+ it "loads nested models" do
79
+ pending
80
+ neighborhoods = City.first.neighborhoods
81
+ neighborhoods.first.should be_a Neighborhood
82
+ end
83
+ end
58
84
  end
59
85
  end
data/structure.gemspec CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
18
18
 
19
19
  {
20
20
  'activesupport' => '>= 3.0',
21
+ 'rake' => '~> 0.9',
21
22
  'rspec' => '~> 2.6',
22
23
  'ruby-debug19' => '~> 0.11.6'
23
24
  }.each do |lib, version|
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 12
8
- - 1
9
- version: 0.12.1
8
+ - 2
9
+ version: 0.12.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Paper Cavalier
@@ -14,12 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-07-07 00:00:00 +01:00
17
+ date: 2011-07-25 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activesupport
22
- prerelease: false
23
22
  requirement: &id001 !ruby/object:Gem::Requirement
24
23
  none: false
25
24
  requirements:
@@ -30,11 +29,25 @@ dependencies:
30
29
  - 0
31
30
  version: "3.0"
32
31
  type: :development
32
+ prerelease: false
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
35
- name: rspec
36
- prerelease: false
35
+ name: rake
37
36
  requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 9
44
+ version: "0.9"
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &id003 !ruby/object:Gem::Requirement
38
51
  none: false
39
52
  requirements:
40
53
  - - ~>
@@ -44,11 +57,11 @@ dependencies:
44
57
  - 6
45
58
  version: "2.6"
46
59
  type: :development
47
- version_requirements: *id002
60
+ prerelease: false
61
+ version_requirements: *id003
48
62
  - !ruby/object:Gem::Dependency
49
63
  name: ruby-debug19
50
- prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
64
+ requirement: &id004 !ruby/object:Gem::Requirement
52
65
  none: false
53
66
  requirements:
54
67
  - - ~>
@@ -59,7 +72,8 @@ dependencies:
59
72
  - 6
60
73
  version: 0.11.6
61
74
  type: :development
62
- version_requirements: *id003
75
+ prerelease: false
76
+ version_requirements: *id004
63
77
  description: Structure is a key/value container for modeling ephemeral data.
64
78
  email:
65
79
  - code@papercavalier.com
@@ -79,10 +93,10 @@ files:
79
93
  - Rakefile
80
94
  - benchmark.rb
81
95
  - lib/structure.rb
82
- - lib/structure/json.rb
83
96
  - lib/structure/static.rb
84
97
  - lib/structure/version.rb
85
98
  - spec/fixtures/cities.yml
99
+ - spec/fixtures/cities_with_neighborhoods.yml
86
100
  - spec/fixtures/cities_without_id.yml
87
101
  - spec/models/book.rb
88
102
  - spec/models/city.rb
@@ -106,6 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
120
  requirements:
107
121
  - - ">="
108
122
  - !ruby/object:Gem::Version
123
+ hash: 2262708410600119149
109
124
  segments:
110
125
  - 0
111
126
  version: "0"
@@ -114,6 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
129
  requirements:
115
130
  - - ">="
116
131
  - !ruby/object:Gem::Version
132
+ hash: 2262708410600119149
117
133
  segments:
118
134
  - 0
119
135
  version: "0"
@@ -126,6 +142,7 @@ specification_version: 3
126
142
  summary: A key/value container for modeling ephemeral data
127
143
  test_files:
128
144
  - spec/fixtures/cities.yml
145
+ - spec/fixtures/cities_with_neighborhoods.yml
129
146
  - spec/fixtures/cities_without_id.yml
130
147
  - spec/models/book.rb
131
148
  - spec/models/city.rb
@@ -1,41 +0,0 @@
1
- unless Object.const_defined?(:JSON) and ::JSON.const_defined?(:JSON_LOADED) and
2
- ::JSON::JSON_LOADED
3
- require 'json'
4
- end
5
-
6
- class Structure
7
- def self.json_create(object)
8
- object.delete('json_class')
9
- new(object)
10
- end
11
-
12
- def to_json(*args)
13
- klass = self.class.name
14
- { JSON.create_id => klass }.
15
- merge(@attributes).
16
- to_json(*args)
17
- end
18
- end
19
-
20
- if defined? ActiveSupport
21
- class Structure
22
- def as_json(options = nil)
23
- # create a subset of the attributes by applying :only or :except
24
- subset = if options
25
- if attrs = options[:only]
26
- @attributes.slice(*Array.wrap(attrs))
27
- elsif attrs = options[:except]
28
- @attributes.except(*Array.wrap(attrs))
29
- else
30
- @attributes.dup
31
- end
32
- else
33
- @attributes.dup
34
- end
35
-
36
- klass = self.class.name
37
- { JSON.create_id => klass }.
38
- merge(subset)
39
- end
40
- end
41
- end