bipolar 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Ryan Angilly
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 ADDED
@@ -0,0 +1,30 @@
1
+ = Bipolar
2
+
3
+ class Asset
4
+ include MongoMapper::Document
5
+ plugin Bipolar
6
+
7
+ embeds_many :images
8
+ end
9
+
10
+ class Image
11
+ include MongoMapper::Document
12
+ end
13
+
14
+
15
+ Image.create! options
16
+ Image.create! other_options
17
+
18
+ Asset.create :images => Image.all
19
+
20
+ The last line will embed the images inside the asset. The images will remain as first-class documents,
21
+ and will be untouched.
22
+
23
+ = License
24
+
25
+ bipolar is released under the MIT license.
26
+
27
+
28
+ = Support
29
+
30
+ Just email me at ryan@angilly.com with questions, bugs, or patches.
@@ -0,0 +1,19 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gemspec|
4
+ gemspec.name = "bipolar"
5
+ gemspec.summary = "MongoMapper plugin for first-class documents that can also be embedded"
6
+ gemspec.description = ""
7
+ gemspec.email = "ryan@angilly.com"
8
+ gemspec.homepage = "http://github.com/ryana/bipolar"
9
+ gemspec.authors = ["Ryan Angilly"]
10
+
11
+ gemspec.add_development_dependency 'shoulda', '2.11.0'
12
+ gemspec.add_development_dependency 'mocha', '0.9.8'
13
+ gemspec.add_development_dependency 'mongo_mapper', '0.8.2'
14
+ gemspec.add_development_dependency 'ruby-debug', '0.10.3'
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler not available. Install it with: gem install jeweler"
19
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,76 @@
1
+ module Bipolar
2
+ Version = '0.1.0'
3
+
4
+ module Embedded; end
5
+
6
+ def self.configure(model)
7
+ model.class_inheritable_accessor :bipolar_associations
8
+ model.bipolar_associations = Set.new
9
+ end
10
+
11
+ module ClassMethods
12
+ def embeds_one name, options = {}
13
+ one "embedded_#{name}", options.reverse_merge(:class => embedded_klass(name), :in => name)
14
+
15
+ class_eval <<-EOF
16
+ def #{name}
17
+ if embedded_#{name}.attributes.nil?
18
+ nil
19
+ else
20
+ # self.class.associated_klass("#{name}").new embedded_#{name}.attributes
21
+ embedded_#{name}
22
+ end
23
+ end
24
+
25
+ def #{name}= val
26
+ if val.nil?
27
+ self.embedded_#{name} = nil
28
+ else
29
+ self.embedded_#{name} = self.class.embedded_klass(val.class).new(val.attributes)
30
+ end
31
+ end
32
+ EOF
33
+ end
34
+
35
+ def embeds_many name, options = {}
36
+ many "embedded_#{name}", options.reverse_merge(:class => embedded_klass(name), :in => name)
37
+
38
+ class_eval <<-EOF
39
+ def #{name}
40
+ (embedded_#{name} || []).map do |e|
41
+ #self.class.associated_klass("#{name}").new e.attributes
42
+ e
43
+ end
44
+ end
45
+
46
+ def #{name}= val
47
+ if val.nil?
48
+ self.embedded_#{name} = []
49
+ else
50
+ self.embedded_#{name} = val.map do |v|
51
+ self.class.embedded_klass(v.class).new(v.attributes)
52
+ end
53
+ end
54
+ end
55
+ EOF
56
+ end
57
+
58
+
59
+ def associated_klass(name)
60
+ name.to_s.singularize.camelize.constantize
61
+ end
62
+
63
+ def embedded_klass(name)
64
+ if !Bipolar::Embedded.const_defined? associated_klass(name).to_s
65
+ associated_klass(name).class_eval <<-EOF
66
+ class Bipolar::Embedded::#{associated_klass(name)} < self
67
+ include MongoMapper::EmbeddedDocument
68
+ end
69
+ EOF
70
+ end
71
+
72
+ Bipolar::Embedded.const_get associated_klass(name).to_s
73
+ end
74
+ end
75
+
76
+ end
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ require 'shoulda'
3
+ require 'mocha'
4
+ require 'ruby-debug'
5
+ require 'mongo_mapper'
6
+ MongoMapper.database = 'bipolar-test'
7
+
8
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
9
+
10
+ require 'bipolar'
@@ -0,0 +1,153 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class Doc
4
+ include MongoMapper::Document
5
+ end
6
+
7
+ class Image
8
+ include MongoMapper::Document
9
+ end
10
+
11
+ class BipolarTest < Test::Unit::TestCase
12
+
13
+ def teardown
14
+ Doc.all.each &:destroy
15
+ Image.all.each &:destroy
16
+ end
17
+
18
+ should "have Bipolar" do
19
+ assert Bipolar
20
+ end
21
+
22
+ context "A Doc w/ Bipolar plugged in" do
23
+ setup do
24
+ Doc.plugin Bipolar
25
+ end
26
+
27
+ should "have bipolar associations" do
28
+ assert Doc.bipolar_associations.is_a?(Set)
29
+ end
30
+
31
+ context "that embeds_many :images" do
32
+ setup do
33
+ Doc.embeds_many :images
34
+ @doc = Doc.new
35
+ end
36
+
37
+ should "have embedded_images" do
38
+ assert @doc.respond_to?(:embedded_images=)
39
+ assert @doc.respond_to?(:embedded_images)
40
+ end
41
+
42
+ should "have images" do
43
+ assert @doc.respond_to?(:images=)
44
+ assert @doc.respond_to?(:images)
45
+ end
46
+
47
+ context "with a bunch of images" do
48
+ setup do
49
+ @images = [Image.create!(:name => 'Ryan'), Image.create!(:name => 'Blake')]
50
+ @doc.images = @images
51
+ @doc.save!
52
+ end
53
+
54
+ should "assign multiple documents" do
55
+ assert_equal @images.map(&:_id), Doc.first.embedded_images.map(&:_id)
56
+ assert_equal @images, Doc.first.images
57
+ assert Doc.first.attributes.include?("embedded_images")
58
+ assert Doc.first.attributes["embedded_images"].is_a? Array
59
+ end
60
+
61
+ should "be able to clear the list with nil" do
62
+ @doc.images = nil
63
+ @doc.save!
64
+
65
+ @doc.reload
66
+ assert_equal [], @doc.images
67
+ end
68
+
69
+ should "be able to clear the list with []" do
70
+ @doc.images = []
71
+ @doc.save!
72
+
73
+ @doc.reload
74
+ assert_equal [], @doc.images
75
+ end
76
+ end
77
+ end
78
+
79
+ context "that embeds_one :image" do
80
+ setup do
81
+ Doc.embeds_one :image
82
+ @doc = Doc.new
83
+ end
84
+
85
+ should "have image" do
86
+ assert @doc.respond_to?(:image=)
87
+ assert @doc.respond_to?(:image)
88
+ end
89
+
90
+ should "have embedded_image" do
91
+ assert @doc.respond_to?(:embedded_image=)
92
+ assert @doc.respond_to?(:embedded_image)
93
+ end
94
+
95
+ should "assign a regular image" do
96
+ @doc.image = Image.new
97
+ @doc.save
98
+ assert Doc.first.image
99
+ end
100
+
101
+ should "assign a regular document" do
102
+ @doc.image = Image.create
103
+ @doc.save
104
+ assert Doc.first.image
105
+ end
106
+
107
+ should "wrap regular document assignments in embedded classes" do
108
+ img = Image.new :name => 'Ryan'
109
+ @doc.image = img
110
+ assert_equal 'Ryan', @doc.embedded_image.name
111
+ end
112
+
113
+ should "embed a regular document" do
114
+ @doc.image = Image.new :name => 'Ryan'
115
+ assert @doc.save
116
+
117
+ assert_equal 'Ryan', Doc.first.image.name
118
+ end
119
+
120
+ context "with an embedded created image" do
121
+ setup do
122
+ @img = Image.create! :name => 'Ryan', :age => 27
123
+ @doc.image = @img
124
+ @doc.save!
125
+ end
126
+
127
+ should "be able to edit embedded document" do
128
+ d = Doc.first
129
+ d.image.name = 'Doug'
130
+ d.save!
131
+
132
+ d = Doc.first
133
+ assert_equal 'Doug', d.image.name
134
+ assert_equal 'Ryan', Image.first.name
135
+ end
136
+
137
+ should "embed a created object" do
138
+ assert_equal 1, Image.count
139
+ assert_equal @img.attributes.except('_type'), Doc.first.image.attributes.except('_type')
140
+ end
141
+
142
+ should "destroy an embedded doc" do
143
+ d = Doc.first
144
+ d.image = nil
145
+ d.save!
146
+
147
+ od = Doc.first
148
+ assert_nil od.image
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,2 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bipolar
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Ryan Angilly
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-25 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: shoulda
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 11
30
+ - 0
31
+ version: 2.11.0
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: mocha
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 9
44
+ - 8
45
+ version: 0.9.8
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: mongo_mapper
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ - 8
58
+ - 2
59
+ version: 0.8.2
60
+ type: :development
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: ruby-debug
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ - 10
72
+ - 3
73
+ version: 0.10.3
74
+ type: :development
75
+ version_requirements: *id004
76
+ description: ""
77
+ email: ryan@angilly.com
78
+ executables: []
79
+
80
+ extensions: []
81
+
82
+ extra_rdoc_files:
83
+ - README
84
+ files:
85
+ - MIT-LICENSE
86
+ - README
87
+ - Rakefile
88
+ - VERSION
89
+ - lib/bipolar.rb
90
+ - test/test_helper.rb
91
+ - test/unit/test_bipolar.rb
92
+ - test/unit/test_helper.rb
93
+ has_rdoc: true
94
+ homepage: http://github.com/ryana/bipolar
95
+ licenses: []
96
+
97
+ post_install_message:
98
+ rdoc_options:
99
+ - --charset=UTF-8
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ segments:
107
+ - 0
108
+ version: "0"
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ segments:
114
+ - 0
115
+ version: "0"
116
+ requirements: []
117
+
118
+ rubyforge_project:
119
+ rubygems_version: 1.3.6
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: MongoMapper plugin for first-class documents that can also be embedded
123
+ test_files:
124
+ - test/test_helper.rb
125
+ - test/unit/test_bipolar.rb
126
+ - test/unit/test_helper.rb