json_mapper 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ .document
2
+ Gemfile.lock
3
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source :rubygems
2
+
3
+ gem "json", ">= 1.4.3"
4
+
5
+ group :development do
6
+ gem "shoulda", ">= 2.10.3"
7
+ gem "mcmire-matchy", ">= 0.5.2"
8
+ gem "mocha", ">= 0.9.8"
9
+ end
10
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Trond Arve Nordheim
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,95 @@
1
+ = JSON Mapper
2
+ by Trond Arve Nordheim -
3
+ {Binary Marbles}[http://www.binarymarbles.com/]
4
+
5
+ == NOTICE
6
+
7
+ This is a project under heavy development. The API is far from stable yet, and
8
+ the code is very unclean in some places. The API won't be considered stable
9
+ until full tests are available verifying that all functionality is working as
10
+ expected.
11
+
12
+ == Description
13
+
14
+ A Ruby gem for mapping data from JSON data structures into Ruby class representations.
15
+
16
+ == Features
17
+
18
+ * Simple one to one mappings
19
+ * Complex mappings (many to one)
20
+ * Associations
21
+ * Type checking
22
+
23
+ == Usage
24
+
25
+ === Simple one to one mapping
26
+ class Model
27
+
28
+ include JSONMapper
29
+
30
+ # Map the "id" attribute from the JSON data structure to the id attribute of the class,
31
+ # using Integer as the data type
32
+ json_attribute :id, Integer
33
+
34
+ # Map the "model_title" attribute from the JSON data structure to the title attribute of
35
+ # the class, using String as the data type
36
+ json_attribute :title, :model_title, String
37
+
38
+ end
39
+
40
+ === Complex many to one mapping
41
+ class Model
42
+
43
+ include JSONMapper
44
+
45
+ # Map the "id", "model_id" or "modelid" attribute (whatever is located first) from the
46
+ # JSON data structure to the id attribute of the class, using Integer as the data type
47
+ json_attribute :id, [ :id, :model_id, :modelid ], Integer
48
+
49
+ end
50
+
51
+ === Associations
52
+ class AssociatedClass
53
+
54
+ include JSONMapper
55
+
56
+ # Map the "id" of the JSON data structure to the id attribute of the class, using
57
+ # Integer as the data type
58
+ json_attribute :id, Integer
59
+
60
+ end
61
+
62
+ class Model
63
+
64
+ include JSONMapper
65
+
66
+ # Map the "association" attribute from the JSON data structure to an instance of
67
+ # the AssociatedClass class, mapping it to the association attribute of the class.
68
+ json_attribute :association, AssociatedClass
69
+
70
+ # Map all entries in the "associations" array from the JSON data structure to
71
+ # an array of AssociatedClass instances, mapping them to the associations attribute
72
+ # of the class
73
+ json_attributes :associations, AssociatedClass
74
+
75
+ end
76
+
77
+ == Requirements
78
+
79
+ * {json}[http://rubygems.org/gems/json]
80
+
81
+ == Installation
82
+
83
+ $ gem install json_mapper
84
+
85
+ == Note on Patches/Pull Requests
86
+
87
+ * Fork the project.
88
+ * Make your feature addition or bug fix.
89
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
90
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
91
+ * Send me a pull request. Bonus points for topic branches.
92
+
93
+ == Copyright
94
+
95
+ Copyright (c) 2010 Trond Arve Nordheim. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ require "rake"
2
+ require "jeweler"
3
+ require "bundler"
4
+ require "rake/testtask"
5
+
6
+ # Gemcutter/Jeweler configuration
7
+ # ----------------------------------------------------------------------------
8
+ Jeweler::Tasks.new do |gem|
9
+
10
+ gem.name = "json_mapper"
11
+ gem.summary = "Ruby gem for mapping JSON data structures to Ruby classes"
12
+ gem.email = "tanordheim@gmail.com"
13
+ gem.homepage = "http://github.com/tanordheim/json_mapper"
14
+ gem.authors = [ "Trond Arve Nordheim" ]
15
+
16
+ gem.add_bundler_dependencies
17
+
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+
21
+ # Test setup
22
+ # ----------------------------------------------------------------------------
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << "lib" << "test"
25
+ test.ruby_opts << "-rubygems"
26
+ test.pattern = "test/**/*_test.rb"
27
+ test.verbose = true
28
+ end
29
+
30
+ # Task setups
31
+ # ----------------------------------------------------------------------------
32
+ task :test => :check_dependencies
33
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ directory = File.expand_path(File.dirname(__FILE__))
2
+ require File.join(directory, "lib", "json_mapper")
@@ -0,0 +1,71 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{json_mapper}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Trond Arve Nordheim"]
12
+ s.date = %q{2010-08-08}
13
+ s.email = %q{tanordheim@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ ".gitignore",
21
+ "Gemfile",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "init.rb",
27
+ "json_mapper.gemspec",
28
+ "lib/json_mapper.rb",
29
+ "lib/json_mapper/attribute.rb",
30
+ "lib/json_mapper/attribute_list.rb",
31
+ "test.rb",
32
+ "test/fixtures/complex.json",
33
+ "test/fixtures/simple.json",
34
+ "test/json_mapper_test.rb",
35
+ "test/support/models.rb",
36
+ "test/test_helper.rb"
37
+ ]
38
+ s.homepage = %q{http://github.com/tanordheim/json_mapper}
39
+ s.rdoc_options = ["--charset=UTF-8"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.3.7}
42
+ s.summary = %q{Ruby gem for mapping JSON data structures to Ruby classes}
43
+ s.test_files = [
44
+ "test/support/models.rb",
45
+ "test/test_helper.rb",
46
+ "test/json_mapper_test.rb"
47
+ ]
48
+
49
+ if s.respond_to? :specification_version then
50
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
+ s.specification_version = 3
52
+
53
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
+ s.add_runtime_dependency(%q<json>, [">= 1.4.3"])
55
+ s.add_development_dependency(%q<shoulda>, [">= 2.10.3"])
56
+ s.add_development_dependency(%q<mcmire-matchy>, [">= 0.5.2"])
57
+ s.add_development_dependency(%q<mocha>, [">= 0.9.8"])
58
+ else
59
+ s.add_dependency(%q<json>, [">= 1.4.3"])
60
+ s.add_dependency(%q<shoulda>, [">= 2.10.3"])
61
+ s.add_dependency(%q<mcmire-matchy>, [">= 0.5.2"])
62
+ s.add_dependency(%q<mocha>, [">= 0.9.8"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<json>, [">= 1.4.3"])
66
+ s.add_dependency(%q<shoulda>, [">= 2.10.3"])
67
+ s.add_dependency(%q<mcmire-matchy>, [">= 0.5.2"])
68
+ s.add_dependency(%q<mocha>, [">= 0.9.8"])
69
+ end
70
+ end
71
+
@@ -0,0 +1,144 @@
1
+ require "json"
2
+
3
+ class Boolean; end
4
+
5
+ module JSONMapper
6
+
7
+ def self.included(base)
8
+ base.instance_variable_set("@attributes", {})
9
+ base.extend ClassMethods
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ def json_attribute(name, *args)
15
+
16
+ source_attributes, type = extract_attribute_data(name, *args)
17
+ attribute = Attribute.new(name, source_attributes, type)
18
+ @attributes[to_s] ||= []
19
+ @attributes[to_s] << attribute
20
+
21
+ attr_accessor attribute.method_name.to_sym
22
+
23
+ end
24
+
25
+ def json_attributes(name, *args)
26
+
27
+ source_attributes, type = extract_attribute_data(name, *args)
28
+ attribute = AttributeList.new(name, source_attributes, type)
29
+ @attributes[to_s] ||= []
30
+ @attributes[to_s] << attribute
31
+
32
+ attr_accessor attribute.method_name.to_sym
33
+
34
+ end
35
+
36
+ def attributes
37
+ @attributes[to_s] || []
38
+ end
39
+
40
+ def parse(data)
41
+
42
+ # Parse the data into a hash
43
+ json = JSON.parse(data, { :symbolize_names => true })
44
+
45
+ # Parse the JSON data structure
46
+ parse_json(json)
47
+
48
+ end
49
+
50
+ def parse_json(json)
51
+
52
+ # Create a new instance of ourselves
53
+ instance = new
54
+
55
+ # Instantiate all AttributeList instances
56
+ attributes.each do |attribute|
57
+ if attribute.is_a?(AttributeList)
58
+ instance.send("#{attribute.name}=", attribute.dup)
59
+ end
60
+ end
61
+
62
+ # Traverse all defined attributes and assign data from the
63
+ # JSON data structure
64
+ attributes.each do |attribute|
65
+ if is_mapped?(attribute, json)
66
+ value = mapping_value(attribute, json)
67
+ if attribute.is_a?(AttributeList)
68
+ value = [ value ] unless value.is_a?(Array)
69
+ value.each do |v|
70
+ instance.send("#{attribute.name}") << build_attribute(attribute.name, attribute.type).typecast(v)
71
+ end
72
+ else
73
+ instance.send("#{attribute.name}=".to_sym, attribute.typecast(value))
74
+ end
75
+ end
76
+ end
77
+
78
+ instance
79
+
80
+ end
81
+
82
+ private
83
+
84
+ def build_attribute(name, type)
85
+ Attribute.new(name, name, type)
86
+ end
87
+
88
+ def extract_attribute_data(name, *args)
89
+
90
+ # If args is not an array, or it contains 0 elements,
91
+ # throw an argument error as we at least need the data
92
+ # type for the mapping specified.
93
+ if !args.is_a?(Array) || args.empty?
94
+ raise ArgumentError.new("Type parameter is required")
95
+ end
96
+
97
+ # If the first argument is a symbol or an array, that's
98
+ # a specific source attribute mapping. If not, use the
99
+ # specified name as the source attribute name.
100
+ if args[0].is_a?(Symbol) || args[0].is_a?(Array)
101
+ source_attributes = args.delete_at(0)
102
+ else
103
+ source_attributes = name
104
+ end
105
+
106
+ # The remaining first argument must be a valid data type
107
+ if args[0].is_a?(Class)
108
+ type = args[0]
109
+ else
110
+ raise ArgumentError.new("Invalid type parameter specified")
111
+ end
112
+
113
+ return source_attributes, type
114
+
115
+ end
116
+
117
+ def is_mapped?(attribute, json)
118
+
119
+ attribute.source_attributes.each do |source_attribute|
120
+ if json.key?(source_attribute)
121
+ return true
122
+ end
123
+ end
124
+ return false
125
+
126
+ end
127
+
128
+ def mapping_value(attribute, json)
129
+
130
+ attribute.source_attributes.each do |source_attribute|
131
+ if json.key?(source_attribute)
132
+ return json[source_attribute]
133
+ end
134
+ end
135
+ return nil
136
+
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+
143
+ require "json_mapper/attribute"
144
+ require "json_mapper/attribute_list"
@@ -0,0 +1,40 @@
1
+ class Attribute
2
+
3
+ attr_accessor :name, :source_attributes, :type
4
+
5
+ Types = [ String, Integer, Boolean ]
6
+
7
+ def initialize(name, source_attributes, type)
8
+
9
+ self.name = name
10
+ self.source_attributes = source_attributes.is_a?(Array) ? source_attributes : [ source_attributes ]
11
+ self.type = type
12
+
13
+ end
14
+
15
+ def method_name
16
+ @method_name ||= self.name.to_s.tr("-", "_")
17
+ end
18
+
19
+ def typecast(value)
20
+
21
+ return value if value.nil?
22
+
23
+ if self.type == String then return value.to_s
24
+ elsif self.type == Integer then return value.to_i
25
+ elsif self.type == Boolean then return value.to_s == "true"
26
+ else
27
+
28
+ # If our type is a JSONMapper instance, delegate the
29
+ # mapping to that class
30
+ if self.type.new.is_a?(JSONMapper)
31
+ return self.type.parse_json(value)
32
+ else
33
+ return value
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,20 @@
1
+ class AttributeList < ::Array
2
+
3
+ attr_accessor :name, :source_attributes, :type
4
+
5
+ def initialize(name, source_attributes, type)
6
+
7
+ self.name = name
8
+ self.source_attributes = source_attributes.is_a?(Array) ? source_attributes : [ source_attributes ]
9
+ self.type = type
10
+
11
+ end
12
+
13
+ def method_name
14
+ @method_name ||= self.name.to_s.tr("-", "_")
15
+ end
16
+
17
+ def typecast
18
+ end
19
+
20
+ end
data/test.rb ADDED
@@ -0,0 +1,28 @@
1
+ module TestModule
2
+ def self.included(base)
3
+ base.extend ClassMethods
4
+ end
5
+
6
+ module ClassMethods
7
+ def foo
8
+ attr_accessor :test
9
+ end
10
+ end
11
+ end
12
+
13
+ class TestClass
14
+ include TestModule
15
+ foo
16
+ end
17
+
18
+ t = TestClass.new
19
+ t.test = "test"
20
+ puts "Test is #{t.test}"
21
+
22
+ t2 = Class.new do
23
+ include TestModule
24
+ foo
25
+ end
26
+
27
+ t2.test = "foo"
28
+ puts "Test is #{t2.test}"
@@ -0,0 +1,21 @@
1
+ {
2
+ "id": 1,
3
+ "title": "Complex JSON title",
4
+ "simple": {
5
+ "id": 1,
6
+ "title": "Simple JSON title",
7
+ "boolean": true
8
+ },
9
+ "simples": [
10
+ {
11
+ "id": 1,
12
+ "title": "Simple JSON title #1",
13
+ "boolean": true
14
+ },
15
+ {
16
+ "id": 2,
17
+ "title": "Simple JSON title #2",
18
+ "boolean": true
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "id": 1,
3
+ "title": "Simple JSON title",
4
+ "boolean": true
5
+ }
@@ -0,0 +1,104 @@
1
+ require "test_helper"
2
+ require "support/models"
3
+
4
+ class JSONMapperTest < Test::Unit::TestCase
5
+
6
+ context "included in a model class" do
7
+
8
+ setup do
9
+ @klass = Class.new do
10
+ include JSONMapper
11
+ def to_s
12
+ "TestUnitClass"
13
+ end
14
+ end
15
+ end
16
+
17
+ should "initialize empty attributes array" do
18
+ @klass.attributes.should == []
19
+ end
20
+
21
+ should "allow adding a simple attribute mapping" do
22
+
23
+ @klass.json_attribute :id, Integer
24
+
25
+ @klass.attributes.size.should == 1
26
+ @klass.attributes.first.name.should == :id
27
+ @klass.attributes.first.source_attributes.should == [ :id ]
28
+ @klass.attributes.first.type.should == Integer
29
+ @klass.attributes.first.method_name.should == "id"
30
+
31
+ end
32
+
33
+ should "allow adding a complex attribute mapping" do
34
+ @klass.json_attribute :id, [ :id, :attribute_id, :foo_id ], Integer
35
+ @klass.attributes.size.should == 1
36
+ @klass.attributes.first.name.should == :id
37
+ @klass.attributes.first.source_attributes.should == [ :id, :attribute_id, :foo_id ]
38
+ @klass.attributes.first.type.should == Integer
39
+ @klass.attributes.first.method_name.should == "id"
40
+ end
41
+
42
+ should "parse simple json structure into a ruby object" do
43
+ model = SimpleModel.parse(fixture_file("simple.json"))
44
+ model.id.should == 1
45
+ model.title.should == "Simple JSON title"
46
+ model.boolean.should == true
47
+ end
48
+
49
+ should "assign value from different sources into an attribute" do
50
+
51
+ model = ComplexModel.parse('{ "id": 1 }')
52
+ model.id.should == 1
53
+
54
+ model = ComplexModel.parse('{ "attribute_id": 1 }')
55
+ model.id.should == 1
56
+
57
+ end
58
+
59
+ should "not overwrite initial value when assigning values from different sources into an attribute" do
60
+
61
+ model = ComplexModel.parse('{ "id": 1, "attribute_id": 2 }')
62
+ model.id.should == 1
63
+
64
+ end
65
+
66
+ should "assign another model into an attribute" do
67
+
68
+ model = ComplexModel.parse('{ "simple": { "id": 1 } }')
69
+ model.simple.id.should == 1
70
+
71
+ end
72
+
73
+ should "assign an array into an attribute" do
74
+
75
+ model = ComplexModel.parse('{ "integers": [ 1, 2, 3 ] }')
76
+ model.integers.should == [ 1, 2, 3 ]
77
+
78
+ end
79
+
80
+ should "assign an array of models into an attribute" do
81
+
82
+ model = ComplexModel.parse('{ "simples": [{ "id": 1 }, { "id": 2 }] }')
83
+ model.simples.size.should == 2
84
+ model.simples.first.id.should == 1
85
+ model.simples.last.id.should == 2
86
+
87
+ end
88
+
89
+ should "parse complex json structure into a ruby object" do
90
+ model = ComplexModel.parse(fixture_file("complex.json"))
91
+ model.id.should == 1
92
+ model.model_title.should == "Complex JSON title"
93
+ model.simple.id.should == 1
94
+ model.simple.title.should == "Simple JSON title"
95
+ model.simples.size.should == 2
96
+ model.simples.first.id.should == 1
97
+ model.simples.first.title.should == "Simple JSON title #1"
98
+ model.simples.last.id.should == 2
99
+ model.simples.last.title.should == "Simple JSON title #2"
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,21 @@
1
+ class SimpleModel
2
+
3
+ include JSONMapper
4
+
5
+ json_attribute :id, Integer
6
+ json_attribute :title, String
7
+ json_attribute :boolean, Boolean
8
+
9
+ end
10
+
11
+ class ComplexModel
12
+
13
+ include JSONMapper
14
+
15
+ json_attribute :id, [ :id, :attribute_id ], Integer
16
+ json_attribute :model_title, :title, String
17
+ json_attribute :simple, SimpleModel
18
+ json_attributes :simples, SimpleModel
19
+ json_attributes :integers, Integer
20
+
21
+ end
@@ -0,0 +1,20 @@
1
+ require "test/unit"
2
+ require "shoulda"
3
+ require "matchy"
4
+ require "mocha"
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require "json_mapper"
9
+
10
+ class Test::Unit::TestCase
11
+ end
12
+
13
+ # Load a fixture file and return the contents
14
+ def fixture_file(filename)
15
+
16
+ return "" if filename == ""
17
+ file_path = File.expand_path(File.dirname(__FILE__) + "/fixtures/" + filename)
18
+ File.read(file_path)
19
+
20
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: json_mapper
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Trond Arve Nordheim
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-08 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ name: json
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 1
32
+ - 4
33
+ - 3
34
+ version: 1.4.3
35
+ requirement: *id001
36
+ type: :runtime
37
+ - !ruby/object:Gem::Dependency
38
+ prerelease: false
39
+ name: shoulda
40
+ version_requirements: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 33
46
+ segments:
47
+ - 2
48
+ - 10
49
+ - 3
50
+ version: 2.10.3
51
+ requirement: *id002
52
+ type: :development
53
+ - !ruby/object:Gem::Dependency
54
+ prerelease: false
55
+ name: mcmire-matchy
56
+ version_requirements: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 15
62
+ segments:
63
+ - 0
64
+ - 5
65
+ - 2
66
+ version: 0.5.2
67
+ requirement: *id003
68
+ type: :development
69
+ - !ruby/object:Gem::Dependency
70
+ prerelease: false
71
+ name: mocha
72
+ version_requirements: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 43
78
+ segments:
79
+ - 0
80
+ - 9
81
+ - 8
82
+ version: 0.9.8
83
+ requirement: *id004
84
+ type: :development
85
+ description:
86
+ email: tanordheim@gmail.com
87
+ executables: []
88
+
89
+ extensions: []
90
+
91
+ extra_rdoc_files:
92
+ - LICENSE
93
+ - README.rdoc
94
+ files:
95
+ - .document
96
+ - .gitignore
97
+ - Gemfile
98
+ - LICENSE
99
+ - README.rdoc
100
+ - Rakefile
101
+ - VERSION
102
+ - init.rb
103
+ - json_mapper.gemspec
104
+ - lib/json_mapper.rb
105
+ - lib/json_mapper/attribute.rb
106
+ - lib/json_mapper/attribute_list.rb
107
+ - test.rb
108
+ - test/fixtures/complex.json
109
+ - test/fixtures/simple.json
110
+ - test/json_mapper_test.rb
111
+ - test/support/models.rb
112
+ - test/test_helper.rb
113
+ has_rdoc: true
114
+ homepage: http://github.com/tanordheim/json_mapper
115
+ licenses: []
116
+
117
+ post_install_message:
118
+ rdoc_options:
119
+ - --charset=UTF-8
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 3
128
+ segments:
129
+ - 0
130
+ version: "0"
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 3
137
+ segments:
138
+ - 0
139
+ version: "0"
140
+ requirements: []
141
+
142
+ rubyforge_project:
143
+ rubygems_version: 1.3.7
144
+ signing_key:
145
+ specification_version: 3
146
+ summary: Ruby gem for mapping JSON data structures to Ruby classes
147
+ test_files:
148
+ - test/support/models.rb
149
+ - test/test_helper.rb
150
+ - test/json_mapper_test.rb