dm-maker 1.0.0

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.
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source :rubygems
2
+
3
+ DM_VERSION = "1.2.0"
4
+
5
+ gem "dm-core", DM_VERSION
6
+ gem "active_support"
7
+ gem "i18n"
8
+
9
+ group :test do
10
+ gem "test-unit"
11
+ gem "rake"
12
+ gem "dm-migrations", DM_VERSION
13
+ gem "dm-transactions", DM_VERSION
14
+ gem "dm-sqlite-adapter", DM_VERSION
15
+ end
data/README ADDED
@@ -0,0 +1,55 @@
1
+ dm-maker
2
+
3
+ DataMapper extension to generate instances from YAML
4
+
5
+
6
+ Examples
7
+ ========
8
+
9
+ (extracted from tests, which provide a more comprehensive overview)
10
+
11
+ Person:
12
+ -
13
+ name: John Doe
14
+ age: 11
15
+ -
16
+ name: Jane Doe
17
+ age: 13
18
+
19
+ associations:
20
+
21
+ Person:
22
+ name: John
23
+ cars:
24
+ -
25
+ name: Herbie
26
+ manufacturer:
27
+ name: VW
28
+ -
29
+ name: KITT
30
+ manufacturer:
31
+ name: Knight Industries
32
+
33
+ ERB expansion:
34
+
35
+ Person:
36
+ <% 2.times do |i| %>
37
+ -
38
+ name: Johnny <%= i + 5 %>
39
+ age: <%= i %>
40
+ <% end %>
41
+
42
+ references:
43
+
44
+ Family:
45
+ -
46
+ $id: f1
47
+ name: Doe
48
+
49
+ Person:
50
+ -
51
+ name: John
52
+ family: { $ref: f1 }
53
+ -
54
+ name: Jane
55
+ family: { $ref: f1 }
@@ -0,0 +1,55 @@
1
+ dm-maker
2
+
3
+ DataMapper extension to generate instances from YAML
4
+
5
+
6
+ Examples
7
+ ========
8
+
9
+ (extracted from tests, which provide a more comprehensive overview)
10
+
11
+ Person:
12
+ -
13
+ name: John Doe
14
+ age: 11
15
+ -
16
+ name: Jane Doe
17
+ age: 13
18
+
19
+ associations:
20
+
21
+ Person:
22
+ name: John
23
+ cars:
24
+ -
25
+ name: Herbie
26
+ manufacturer:
27
+ name: VW
28
+ -
29
+ name: KITT
30
+ manufacturer:
31
+ name: Knight Industries
32
+
33
+ ERB expansion:
34
+
35
+ Person:
36
+ <% 2.times do |i| %>
37
+ -
38
+ name: Johnny <%= i + 5 %>
39
+ age: <%= i %>
40
+ <% end %>
41
+
42
+ references:
43
+
44
+ Family:
45
+ -
46
+ $id: f1
47
+ name: Doe
48
+
49
+ Person:
50
+ -
51
+ name: John
52
+ family: { $ref: f1 }
53
+ -
54
+ name: Jane
55
+ family: { $ref: f1 }
@@ -0,0 +1,12 @@
1
+ # encoding: UTF-8
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+
5
+ require "rake/testtask"
6
+
7
+ Rake::TestTask.new do |task|
8
+ task.libs << "test"
9
+ end
10
+
11
+ desc "Run tests"
12
+ task :default => :test
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "dm-maker/version"
5
+
6
+ DM_VERSION = "1.2.0"
7
+
8
+ Gem::Specification.new do |s|
9
+ s.name = "dm-maker"
10
+ s.version = DataMapper::Maker::VERSION
11
+ s.authors = ["FND"]
12
+ s.summary = "DataMapper extension to generate instances from YAML"
13
+ s.description = "initializes resources from YAML data"
14
+
15
+ s.rubyforge_project = "dm-maker"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- test/test_*`.split("\n")
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "dm-core", DM_VERSION
22
+ s.add_dependency "active_support"
23
+ s.add_dependency "i18n"
24
+ s.add_development_dependency "test-unit"
25
+ s.add_development_dependency "rake"
26
+ s.add_development_dependency "dm-migrations", DM_VERSION
27
+ s.add_development_dependency "dm-transactions", DM_VERSION
28
+ s.add_development_dependency "dm-sqlite-adapter", DM_VERSION
29
+ end
@@ -0,0 +1,82 @@
1
+ # encoding: UTF-8
2
+
3
+ require "yaml"
4
+ require "erb"
5
+ require "active_support"
6
+ require "active_support/core_ext"
7
+ require "active_support/inflector"
8
+
9
+ require "dm-maker/version"
10
+
11
+ module DataMapper
12
+ module Maker
13
+
14
+ REL_TYPES = {
15
+ :to_one => [DataMapper::Associations::ManyToOne::Relationship,
16
+ DataMapper::Associations::OneToOne::Relationship],
17
+ :to_many => [DataMapper::Associations::ManyToMany::Relationship,
18
+ DataMapper::Associations::OneToMany::Relationship]
19
+ }
20
+
21
+ def self.make(data)
22
+ data = load_yaml(data) if data.class == String
23
+
24
+ cache = {}
25
+ return data.each_with_object({}) do |(class_name, instances), hsh|
26
+ klass = class_name.constantize
27
+ hsh[class_name] = instances.map { |instance_data|
28
+ create_instance(klass, instance_data, cache)
29
+ }
30
+ end
31
+ end
32
+
33
+ def self.create_instance(klass, data, cache={}) # TODO: document $id / $ref
34
+ if ref = data.delete("$ref")
35
+ raise ArgumentError if data.length > 0
36
+ return cache[ref]
37
+ end
38
+ id = data.delete("$id")
39
+
40
+ data.each { |key, value|
41
+ rel_name = key.to_sym
42
+ if rel = klass.relationships[rel_name]
43
+ if REL_TYPES[:to_many].include? rel.class
44
+ assoc_class = klass.new. # XXX: hacky
45
+ send(rel_name).relationship.child_model
46
+ value = value.map { |d|
47
+ if custom_class = d.delete("class") # TODO: document
48
+ assoc_class = custom_class.constantize
49
+ end
50
+ create_instance(assoc_class, d, cache)
51
+ }
52
+ elsif REL_TYPES[:to_one].include? rel.class
53
+ assoc_class = (rel.child_model == klass or klass < rel.child_model) ?
54
+ rel.parent_model : rel.child_model
55
+ value = create_instance(assoc_class, value, cache)
56
+ end
57
+ end
58
+ data[key] = value # XXX: dangerous while iterating over that same hash!?
59
+ }
60
+
61
+ instance = klass.new(data)
62
+ begin
63
+ instance.save
64
+ rescue DataMapper::SaveFailureError
65
+ # rely on parent saving -- FIXME: hacky!?
66
+ end
67
+
68
+ cache[id] = instance if id
69
+ return instance
70
+ end
71
+
72
+ def self.load_yaml(yaml)
73
+ yaml = ERB.new(yaml).result # TODO: document
74
+ # hack to retain order in Ruby 1.8
75
+ # TODO: document expectations/constraints (only required for $id / $ref)
76
+ yaml.split("\n\n").each_with_object(ActiveSupport::OrderedHash.new) { |yml, hsh|
77
+ hsh.merge! YAML.load(yml)
78
+ }
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ module DataMapper
4
+ module Maker
5
+ VERSION = "1.0.0"
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ require "dm-core"
4
+ require "dm-transactions"
5
+ require "dm-migrations"
6
+ require "test/unit"
7
+
8
+ require "models"
9
+ require "dm-maker"
10
+
11
+ DataMapper.setup(:default, "sqlite::memory:")
12
+ DataMapper.finalize
13
+ DataMapper.auto_migrate!
14
+ DataMapper::Model.raise_on_save_failure = true
15
+
16
+ def reset_database
17
+ models = DataMapper::Model.descendants
18
+ models.first.transaction do
19
+ models.each(&:destroy!)
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+
3
+ class Person
4
+ include DataMapper::Resource
5
+
6
+ property :id, Serial
7
+ property :name, String
8
+ property :age, Integer
9
+
10
+ belongs_to :family, :required => false
11
+ has n, :cars
12
+
13
+ end
14
+
15
+ class Family
16
+ include DataMapper::Resource
17
+
18
+ property :id, Serial
19
+ property :name, String
20
+
21
+ has n, :members, "Person"
22
+
23
+ end
24
+
25
+ class Car
26
+ include DataMapper::Resource
27
+
28
+ property :id, Serial
29
+ property :name, String
30
+
31
+ belongs_to :manufacturer, "Company"
32
+
33
+ end
34
+
35
+ class Company
36
+ include DataMapper::Resource
37
+
38
+ property :id, Serial
39
+ property :name, String
40
+
41
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: UTF-8
2
+
3
+ require "helper"
4
+
5
+ class AssociationsTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ reset_database
9
+ end
10
+
11
+ def test_supports_to_one_associations
12
+ yaml = <<-EOF
13
+ Person:
14
+ -
15
+ name: John
16
+ family:
17
+ name: Doe
18
+ EOF
19
+ data = DataMapper::Maker.make(yaml)
20
+
21
+ assert_equal 1, Person.count
22
+ assert_equal 1, Family.count
23
+ assert_equal "John", data["Person"][0].name
24
+ assert_equal "Doe", data["Person"][0].family.name
25
+ end
26
+
27
+ def test_supports_to_many_associations
28
+ yaml = <<-EOF
29
+ Family:
30
+ -
31
+ name: Doe
32
+ members:
33
+ -
34
+ name: John
35
+ -
36
+ name: Jane
37
+ EOF
38
+ data = DataMapper::Maker.make(yaml)
39
+
40
+ assert_equal 1, Family.count
41
+ assert_equal 2, Person.count
42
+ assert_equal "Doe", data["Family"][0].name
43
+ assert_equal "John", data["Family"][0].members[0].name
44
+ assert_equal "Jane", data["Family"][0].members[1].name
45
+ end
46
+
47
+ def test_supports_nested_associations
48
+ yaml = <<-EOF
49
+ Family:
50
+ -
51
+ name: Doe
52
+ members:
53
+ -
54
+ name: John
55
+ cars:
56
+ -
57
+ name: Herbie
58
+ manufacturer:
59
+ name: VW
60
+ -
61
+ name: KITT
62
+ manufacturer:
63
+ name: Knight Industries
64
+ EOF
65
+ data = DataMapper::Maker.make(yaml)
66
+
67
+ assert_equal 1, Family.count
68
+ assert_equal 1, Person.count
69
+ assert_equal 2, Car.count
70
+ assert_equal "Herbie", Car.first.name
71
+ assert_equal "KITT", Car.last.name
72
+ assert_equal "VW", Company.first.name
73
+ assert_equal "Knight Industries", Company.last.name
74
+ assert_equal "VW", Family.first.members.first.cars.first.manufacturer.name
75
+ end
76
+
77
+ end
@@ -0,0 +1,94 @@
1
+ # encoding: UTF-8
2
+
3
+ require "helper"
4
+
5
+ class BasicsTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ reset_database
9
+ end
10
+
11
+ def test_accepts_yaml
12
+ yaml = <<-EOF
13
+ Person:
14
+ -
15
+ name: John Doe
16
+ age: 11
17
+ -
18
+ name: Jane Doe
19
+ age: 13
20
+ EOF
21
+ DataMapper::Maker.make(yaml)
22
+
23
+ assert_equal 2, Person.count
24
+ assert_equal "John Doe", Person.first.name
25
+ assert_equal 11, Person.first.age
26
+ assert_equal "Jane Doe", Person.last.name
27
+ assert_equal 13, Person.last.age
28
+ end
29
+
30
+ def test_accepts_plain_objects
31
+ DataMapper::Maker.make({
32
+ "Person" => [
33
+ {
34
+ "name" => "John Doe",
35
+ :age => 11
36
+ }, {
37
+ :name => "Jane Doe",
38
+ :age => 13
39
+ }
40
+ ]
41
+ })
42
+
43
+ assert_equal 2, Person.count
44
+ assert_equal "John Doe", Person.first.name
45
+ assert_equal 11, Person.first.age
46
+ assert_equal "Jane Doe", Person.last.name
47
+ assert_equal 13, Person.last.age
48
+ end
49
+
50
+ def test_returns_instances
51
+ yaml = <<-EOF
52
+ Person:
53
+ -
54
+ name: John
55
+ age: 11
56
+ -
57
+ name: Jane
58
+ age: 13
59
+
60
+ Family:
61
+ -
62
+ name: Doe
63
+ EOF
64
+ data = DataMapper::Maker.make(yaml)
65
+
66
+ assert_equal 2, data.length
67
+ assert_equal 2, data["Person"].length
68
+ assert_equal "John", data["Person"][0].name
69
+ assert_equal 11, data["Person"][0].age
70
+ assert_equal "Jane", data["Person"][1].name
71
+ assert_equal 13, data["Person"][1].age
72
+ assert_equal 1, data["Family"].length
73
+ assert_equal "Doe", data["Family"][0].name
74
+ end
75
+
76
+ def test_supports_ERB_expansion
77
+ yaml = <<-EOF
78
+ Person:
79
+ <% 2.times do |i| %>
80
+ -
81
+ name: Johnny <%= i + 5 %>
82
+ age: <%= i %>
83
+ <% end %>
84
+ EOF
85
+
86
+ data = DataMapper::Maker.make(yaml)
87
+ assert_equal 2, data["Person"].length
88
+ assert_equal "Johnny 5", data["Person"].first.name
89
+ assert_equal 0, data["Person"].first.age
90
+ assert_equal "Johnny 6", data["Person"].last.name
91
+ assert_equal 1, data["Person"].last.age
92
+ end
93
+
94
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+
3
+ require "helper"
4
+
5
+ class ReferencesTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ reset_database
9
+ end
10
+
11
+ def test_supports_internal_references
12
+ yaml = <<-EOF
13
+ Family:
14
+ -
15
+ $id: f1
16
+ name: Doe
17
+
18
+ Person:
19
+ -
20
+ name: John
21
+ family: { $ref: f1 }
22
+ -
23
+ name: Jane
24
+ family: { $ref: f1 }
25
+ EOF
26
+ data = DataMapper::Maker.make(yaml)
27
+
28
+ assert_equal 1, Family.count
29
+ assert_equal 2, Person.count
30
+ assert_equal Person.first.family, Person.last.family
31
+ assert_equal "Doe", Person.first.family.name
32
+ end
33
+
34
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dm-maker
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - FND
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-14 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: dm-core
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - "="
27
+ - !ruby/object:Gem::Version
28
+ hash: 31
29
+ segments:
30
+ - 1
31
+ - 2
32
+ - 0
33
+ version: 1.2.0
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: active_support
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: i18n
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ type: :runtime
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: test-unit
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ type: :development
77
+ version_requirements: *id004
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ prerelease: false
81
+ requirement: &id005 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ type: :development
91
+ version_requirements: *id005
92
+ - !ruby/object:Gem::Dependency
93
+ name: dm-migrations
94
+ prerelease: false
95
+ requirement: &id006 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - "="
99
+ - !ruby/object:Gem::Version
100
+ hash: 31
101
+ segments:
102
+ - 1
103
+ - 2
104
+ - 0
105
+ version: 1.2.0
106
+ type: :development
107
+ version_requirements: *id006
108
+ - !ruby/object:Gem::Dependency
109
+ name: dm-transactions
110
+ prerelease: false
111
+ requirement: &id007 !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - "="
115
+ - !ruby/object:Gem::Version
116
+ hash: 31
117
+ segments:
118
+ - 1
119
+ - 2
120
+ - 0
121
+ version: 1.2.0
122
+ type: :development
123
+ version_requirements: *id007
124
+ - !ruby/object:Gem::Dependency
125
+ name: dm-sqlite-adapter
126
+ prerelease: false
127
+ requirement: &id008 !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - "="
131
+ - !ruby/object:Gem::Version
132
+ hash: 31
133
+ segments:
134
+ - 1
135
+ - 2
136
+ - 0
137
+ version: 1.2.0
138
+ type: :development
139
+ version_requirements: *id008
140
+ description: initializes resources from YAML data
141
+ email:
142
+ executables: []
143
+
144
+ extensions: []
145
+
146
+ extra_rdoc_files: []
147
+
148
+ files:
149
+ - .gitignore
150
+ - Gemfile
151
+ - README
152
+ - README.md
153
+ - Rakefile
154
+ - dm-maker.gemspec
155
+ - lib/dm-maker.rb
156
+ - lib/dm-maker/version.rb
157
+ - test/helper.rb
158
+ - test/models.rb
159
+ - test/test_associations.rb
160
+ - test/test_basics.rb
161
+ - test/test_references.rb
162
+ homepage:
163
+ licenses: []
164
+
165
+ post_install_message:
166
+ rdoc_options: []
167
+
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ hash: 3
176
+ segments:
177
+ - 0
178
+ version: "0"
179
+ required_rubygems_version: !ruby/object:Gem::Requirement
180
+ none: false
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ hash: 3
185
+ segments:
186
+ - 0
187
+ version: "0"
188
+ requirements: []
189
+
190
+ rubyforge_project: dm-maker
191
+ rubygems_version: 1.8.11
192
+ signing_key:
193
+ specification_version: 3
194
+ summary: DataMapper extension to generate instances from YAML
195
+ test_files:
196
+ - test/test_associations.rb
197
+ - test/test_basics.rb
198
+ - test/test_references.rb