mongoid-versioning 0.2.0 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +20 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +2 -1
  5. data/README.md +2 -1
  6. data/Rakefile +3 -5
  7. data/gemfiles/mongoid_master.gemfile +8 -0
  8. data/lib/mongoid/config/locales/en.yml +11 -0
  9. data/lib/mongoid/core_ext/errors/versioning_not_on_root.rb +23 -0
  10. data/lib/mongoid/core_ext/fields/standard.rb +17 -0
  11. data/lib/mongoid/core_ext/fields/validators/macro.rb +11 -0
  12. data/lib/mongoid/core_ext/hierarchy.rb +25 -0
  13. data/lib/mongoid/core_ext/relations/bindings/embedded/many.rb +31 -0
  14. data/lib/mongoid/core_ext/relations/cascading.rb +23 -0
  15. data/lib/mongoid/core_ext/relations/embedded/batchable.rb +36 -0
  16. data/lib/mongoid/core_ext/relations/embedded/many.rb +24 -0
  17. data/lib/mongoid/core_ext/relations/macros.rb +39 -0
  18. data/lib/mongoid/core_ext/relations/metadata.rb +63 -0
  19. data/lib/mongoid/core_ext/relations/options.rb +9 -0
  20. data/lib/mongoid/core_ext/threaded/lifecycle.rb +37 -0
  21. data/lib/mongoid/core_ext/versioning.rb +218 -0
  22. data/lib/mongoid/versioning/version.rb +1 -1
  23. data/lib/mongoid/versioning.rb +16 -213
  24. data/mongoid-versioning.gemspec +2 -2
  25. data/spec/app/models/account.rb +0 -4
  26. data/spec/app/models/acolyte.rb +1 -1
  27. data/spec/app/models/address.rb +2 -2
  28. data/spec/app/models/appointment.rb +1 -1
  29. data/spec/app/models/article.rb +0 -3
  30. data/spec/app/models/building.rb +0 -2
  31. data/spec/app/models/building_address.rb +0 -2
  32. data/spec/app/models/contractor.rb +0 -2
  33. data/spec/app/models/dog.rb +1 -1
  34. data/spec/app/models/drug.rb +0 -2
  35. data/spec/app/models/event.rb +1 -1
  36. data/spec/app/models/game.rb +0 -2
  37. data/spec/app/models/house.rb +1 -2
  38. data/spec/app/models/item.rb +0 -4
  39. data/spec/app/models/name.rb +0 -2
  40. data/spec/app/models/paranoid_phone.rb +2 -0
  41. data/spec/app/models/paranoid_post.rb +3 -1
  42. data/spec/app/models/person.rb +3 -5
  43. data/spec/app/models/player.rb +2 -2
  44. data/spec/app/models/post.rb +2 -2
  45. data/spec/app/models/preference.rb +1 -1
  46. data/spec/app/models/quiz.rb +0 -3
  47. data/spec/app/models/registry.rb +1 -1
  48. data/spec/app/models/symptom.rb +1 -1
  49. data/spec/app/models/tree.rb +1 -1
  50. data/spec/app/models/video.rb +1 -5
  51. data/spec/app/models/wiki_page.rb +0 -2
  52. data/spec/config/mongoid.yml +0 -5
  53. data/spec/mongoid/errors/versioning_not_on_root_spec.rb +29 -0
  54. data/spec/mongoid/relations/macros_spec.rb +17 -0
  55. data/spec/mongoid/relations/metadata_spec.rb +50 -0
  56. data/spec/mongoid/versioning_spec.rb +2 -36
  57. data/spec/spec_helper.rb +4 -3
  58. metadata +44 -30
@@ -1,217 +1,20 @@
1
- # encoding: utf-8
2
- module Mongoid
1
+ require "mongoid/core_ext/errors/versioning_not_on_root.rb"
2
+ require "mongoid/core_ext/fields/standard.rb"
3
+ require "mongoid/core_ext/fields/validators/macro.rb"
4
+ require "mongoid/core_ext/hierarchy.rb"
5
+ require "mongoid/core_ext/relations/bindings/embedded/many.rb"
6
+ require "mongoid/core_ext/relations/cascading.rb"
7
+ require "mongoid/core_ext/relations/embedded/batchable.rb"
8
+ require "mongoid/core_ext/relations/embedded/many.rb"
9
+ require "mongoid/core_ext/relations/macros.rb"
10
+ require "mongoid/core_ext/relations/metadata.rb"
11
+ require "mongoid/core_ext/relations/options.rb"
12
+ require "mongoid/core_ext/threaded/lifecycle.rb"
13
+ require "mongoid/core_ext/versioning.rb"
14
+
15
+ I18n.load_path << File.join(File.dirname(__FILE__), "config", "locales", "en.yml")
3
16
 
4
- # Include this module to get automatic versioning of root level documents.
5
- # This will add a version field to the +Document+ and a has_many association
6
- # with all the versions contained in it.
17
+ module Mongoid
7
18
  module Versioning
8
- extend ActiveSupport::Concern
9
-
10
- included do
11
- field :version, type: Integer, default: 1
12
-
13
- embeds_many \
14
- :versions,
15
- class_name: self.name,
16
- validate: false,
17
- cyclic: true,
18
- inverse_of: nil,
19
- versioned: true
20
-
21
- set_callback :save, :before, :revise, if: :revisable?
22
-
23
- class_attribute :version_max
24
- self.cyclic = true
25
- end
26
-
27
- # Create a new version of the +Document+. This will load the previous
28
- # document from the database and set it as the next version before saving
29
- # the current document. It then increments the version number. If a #max_versions
30
- # limit is set in the model and it's exceeded, the oldest version gets discarded.
31
- #
32
- # @example Revise the document.
33
- # person.revise
34
- #
35
- # @since 1.0.0
36
- def revise
37
- previous = previous_revision
38
- if previous && versioned_attributes_changed?
39
- new_version = versions.build(
40
- previous.versioned_attributes, without_protection: true
41
- )
42
- new_version._id = nil
43
- if version_max.present? && versions.length > version_max
44
- deleted = versions.first
45
- if deleted.paranoid?
46
- versions.delete_one(deleted)
47
- collection.find(atomic_selector).
48
- update({ "$pull" => { "versions" => { "version" => deleted.version }}})
49
- else
50
- versions.delete(deleted)
51
- end
52
- end
53
- self.version = (version || 1 ) + 1
54
- end
55
- end
56
-
57
- # Forces the creation of a new version of the +Document+, regardless of
58
- # whether a change was actually made.
59
- #
60
- # @example Revise the document.
61
- # person.revise!
62
- #
63
- # @since 2.2.1
64
- def revise!
65
- versions.build(
66
- (previous_revision || self).versioned_attributes, without_protection: true
67
- )
68
- versions.shift if version_max.present? && versions.length > version_max
69
- self.version = (version || 1 ) + 1
70
- save
71
- end
72
-
73
- # Filters the results of +changes+ by removing any fields that should
74
- # not be versioned.
75
- #
76
- # @return [ Hash ] A hash of versioned changed attributes.
77
- #
78
- # @since 2.1.0
79
- def versioned_changes
80
- only_versioned_attributes(changes.except("updated_at"))
81
- end
82
-
83
- # Filters the results of +attributes+ by removing any fields that should
84
- # not be versioned.
85
- #
86
- # @return [ Hash ] A hash of versioned attributes.
87
- #
88
- # @since 2.1.0
89
- def versioned_attributes
90
- only_versioned_attributes(attributes)
91
- end
92
-
93
- # Check if any versioned fields have been modified. This is similar
94
- # to +changed?+, except this method also ignores fields set to be
95
- # ignored by versioning.
96
- #
97
- # @return [ Boolean ] Whether fields that will be versioned have changed.
98
- #
99
- # @since 2.1.0
100
- def versioned_attributes_changed?
101
- !versioned_changes.empty?
102
- end
103
-
104
- # Executes a block that temporarily disables versioning. This is for cases
105
- # where you do not want to version on every save.
106
- #
107
- # @example Execute a save without versioning.
108
- # person.versionless(&:save)
109
- #
110
- # @return [ Object ] The document or result of the block execution.
111
- #
112
- # @since 2.0.0
113
- def versionless
114
- @versionless = true
115
- result = yield(self) if block_given?
116
- @versionless = false
117
- result || self
118
- end
119
-
120
- private
121
-
122
- # Find the previous version of this document in the database, or if the
123
- # document had been saved without versioning return the persisted one.
124
- #
125
- # @example Find the last version.
126
- # document.find_last_version
127
- #
128
- # @return [ Document, nil ] The previously saved document.
129
- #
130
- # @since 2.0.0
131
- def previous_revision
132
- _loading_revision do
133
- self.class.unscoped.
134
- where(_id: id).
135
- any_of({ version: version }, { version: nil }).first
136
- end
137
- end
138
-
139
- # Is the document able to be revised? This is true if the document has
140
- # changed and we have not explicitly told it not to version.
141
- #
142
- # @example Is the document revisable?
143
- # document.revisable?
144
- #
145
- # @return [ true, false ] If the document is revisable.
146
- #
147
- # @since 2.0.0
148
- def revisable?
149
- versioned_attributes_changed? && !versionless?
150
- end
151
-
152
- # Are we in versionless mode? This is true if in a versionless block on the
153
- # document.
154
- #
155
- # @example Is the document in versionless mode?
156
- # document.versionless?
157
- #
158
- # @return [ true, false ] Is the document not currently versioning.
159
- #
160
- # @since 2.0.0
161
- def versionless?
162
- @versionless ||= false
163
- end
164
-
165
- # Filters fields that should not be versioned out of an attributes hash.
166
- # Dynamic attributes are always versioned.
167
- #
168
- # @param [ Hash ] A hash with field names as keys.
169
- #
170
- # @return [ Hash ] The hash without non-versioned columns.
171
- #
172
- # @since 2.1.0
173
- def only_versioned_attributes(hash)
174
- versioned = {}
175
- hash.except("versions").each_pair do |name, value|
176
- add_versioned_attribute(versioned, name, value)
177
- end
178
- versioned
179
- end
180
-
181
- # Add the versioned attribute. Will work now for localized fields.
182
- #
183
- # @api private
184
- #
185
- # @example Add the versioned attribute.
186
- # model.add_versioned_attribute({}, "name", "test")
187
- #
188
- # @param [ Hash ] versioned The versioned attributes.
189
- # @param [ String ] name The name of the field.
190
- # @param [ Object ] value The value for the field.
191
- #
192
- # @since 3.0.10
193
- def add_versioned_attribute(versioned, name, value)
194
- field = fields[name]
195
- if field && field.localized?
196
- versioned["#{name}_translations"] = value
197
- else
198
- versioned[name] = value if !field || field.versioned?
199
- end
200
- end
201
-
202
- module ClassMethods
203
-
204
- # Sets the maximum number of versions to store.
205
- #
206
- # @example Set the maximum.
207
- # Person.max_versions(5)
208
- #
209
- # @param [ Integer ] number The maximum number to store.
210
- #
211
- # @return [ Integer ] The max number of versions.
212
- def max_versions(number)
213
- self.version_max = number.to_i
214
- end
215
- end
216
19
  end
217
20
  end
@@ -13,6 +13,6 @@ Gem::Specification.new do |gem|
13
13
  gem.files = `git ls-files`.split("\n")
14
14
  gem.require_path = 'lib'
15
15
 
16
- gem.add_dependency 'activesupport', '>= 3.0'
17
- gem.add_dependency 'mongoid', '~> 3.0'
16
+ gem.add_dependency 'activesupport'
17
+ gem.add_dependency 'mongoid', '4.0.0.beta1'
18
18
  end
@@ -18,10 +18,6 @@ class Account
18
18
  has_and_belongs_to_many :agents
19
19
  has_one :comment, validate: false
20
20
 
21
- attr_accessible :nickname, as: [ :default, :admin ]
22
- attr_accessible :name, as: [ :default, :admin ]
23
- attr_accessible :balance, as: :default
24
-
25
21
  validates_presence_of :name
26
22
  validates_presence_of :nickname, on: :upsert
27
23
  validates_length_of :name, maximum: 10, on: :create
@@ -6,7 +6,7 @@ class Acolyte
6
6
  embeds_many :versions, as: :memorable
7
7
  belongs_to :church
8
8
 
9
- default_scope asc(:name)
9
+ default_scope ->{ asc(:name) }
10
10
  scope :active, ->{ where(status: "active") }
11
11
  scope :named, ->{ where(:name.exists => true) }
12
12
 
@@ -38,8 +38,8 @@ class Address
38
38
  belongs_to :account
39
39
  belongs_to :band
40
40
 
41
- scope :without_postcode, where(postcode: nil)
42
- scope :rodeo, where(street: "Rodeo Dr") do
41
+ scope :without_postcode, ->{ where(postcode: nil) }
42
+ scope :rodeo, ->{ where(street: "Rodeo Dr") } do
43
43
  def mansion?
44
44
  all? { |address| address.street == "Rodeo Dr" }
45
45
  end
@@ -3,5 +3,5 @@ class Appointment
3
3
  field :active, type: Boolean, default: true
4
4
  field :timed, type: Boolean, default: true
5
5
  embedded_in :person
6
- default_scope where(active: true)
6
+ default_scope ->{ where(active: true) }
7
7
  end
@@ -5,9 +5,6 @@ class Article
5
5
  field :is_rss, type: Boolean, default: false
6
6
  field :user_login, type: String
7
7
 
8
- attr_accessible :title, as: [:default, :parser]
9
- attr_accessible :is_rss, as: :parser
10
- attr_accessible :user_login
11
8
  has_and_belongs_to_many :tags, validate: false
12
9
  has_and_belongs_to_many :preferences, inverse_of: nil, validate: false
13
10
  end
@@ -1,7 +1,5 @@
1
1
  class Building
2
2
  include Mongoid::Document
3
- attr_accessible
4
- attr_accessible :building_address, :contractors, as: :admin
5
3
  embeds_one :building_address
6
4
  embeds_many :contractors
7
5
  end
@@ -1,7 +1,5 @@
1
1
  class BuildingAddress
2
2
  include Mongoid::Document
3
- attr_accessible
4
- attr_accessible :city, as: :admin
5
3
  embedded_in :building
6
4
  field :city, type: String
7
5
  end
@@ -1,7 +1,5 @@
1
1
  class Contractor
2
2
  include Mongoid::Document
3
- attr_accessible
4
- attr_accessible :name, as: :admin
5
3
  embedded_in :building
6
4
  field :name, type: String
7
5
  end
@@ -2,5 +2,5 @@ class Dog
2
2
  include Mongoid::Document
3
3
  field :name, type: String
4
4
  has_and_belongs_to_many :breeds
5
- default_scope asc(:name)
5
+ default_scope ->{ asc(:name) }
6
6
  end
@@ -3,6 +3,4 @@ class Drug
3
3
  field :name, type: String
4
4
  field :generic, type: Boolean
5
5
  belongs_to :person, counter_cache: true
6
- attr_accessible :name, as: [ :default, :admin ]
7
- attr_accessible :person_id
8
6
  end
@@ -17,6 +17,6 @@ class Event
17
17
  end
18
18
  end
19
19
 
20
- scope :best, where(:kind.in => [ "party", "concert" ])
20
+ scope :best, ->{ where(:kind.in => [ "party", "concert" ]) }
21
21
  scope :by_kind, ->(kind){ where(:kind.in => [kind]) }
22
22
  end
@@ -13,8 +13,6 @@ class Game
13
13
 
14
14
  validates_format_of :name, without: /\$\$\$/
15
15
 
16
- attr_protected :_id
17
-
18
16
  set_callback(:initialize, :after) do |document|
19
17
  write_attribute("name", "Testing") unless name
20
18
  end
@@ -2,7 +2,6 @@ class House
2
2
  include Mongoid::Document
3
3
  field :name, type: String
4
4
  field :model, type: String
5
- attr_accessible :name, as: [ :default, :admin ]
6
5
 
7
- default_scope asc(:name)
6
+ default_scope ->{ asc(:name) }
8
7
  end
@@ -3,10 +3,6 @@ class Item
3
3
  field :title, type: String
4
4
  field :is_rss, type: Boolean, default: false
5
5
  field :user_login, type: String
6
-
7
- attr_protected :title, as: [:default, :parser]
8
- attr_protected :is_rss, as: :parser
9
- attr_protected :user_login
10
6
  end
11
7
 
12
8
  require "app/models/sub_item"
@@ -15,8 +15,6 @@ class Name
15
15
 
16
16
  accepts_nested_attributes_for :language
17
17
 
18
- attr_protected :_id, :id
19
-
20
18
  def set_parent=(set = false)
21
19
  self.parent_title = namable.title if set
22
20
  end
@@ -1,3 +1,5 @@
1
+ require 'mongoid/paranoia'
2
+
1
3
  class ParanoidPhone
2
4
  include Mongoid::Document
3
5
  include Mongoid::Paranoia
@@ -1,3 +1,5 @@
1
+ require 'mongoid/paranoia'
2
+
1
3
  class ParanoidPost
2
4
  include Mongoid::Document
3
5
  include Mongoid::Versioning
@@ -15,7 +17,7 @@ class ParanoidPost
15
17
  has_many :authors, dependent: :delete
16
18
  has_many :titles, dependent: :restrict
17
19
 
18
- scope :recent, where(created_at: { "$lt" => Time.now, "$gt" => 30.days.ago })
20
+ scope :recent, ->{ where(created_at: { "$lt" => Time.now, "$gt" => 30.days.ago }) }
19
21
 
20
22
  before_destroy :before_destroy_stub
21
23
  after_destroy :after_destroy_stub
@@ -23,7 +23,7 @@ class Person
23
23
  field :owner_id, type: Integer
24
24
  field :security_code
25
25
  field :reading, type: Object
26
- field :bson_id, type: Moped::BSON::ObjectId
26
+ field :bson_id, type: BSON::ObjectId
27
27
  field :pattern, type: Regexp
28
28
  field :override_me, type: Integer
29
29
  field :t, as: :test, type: String
@@ -41,8 +41,6 @@ class Person
41
41
 
42
42
  attr_reader :rescored
43
43
 
44
- attr_protected :security_code, :owner_id, :appointments
45
-
46
44
  embeds_many :favorites, order: :title.desc, inverse_of: :perp, validate: false
47
45
  embeds_many :videos, order: [[ :title, :asc ]], validate: false
48
46
  embeds_many :phone_numbers, class_name: "Phone", validate: false
@@ -123,8 +121,8 @@ class Person
123
121
  accepts_nested_attributes_for :quiz
124
122
  accepts_nested_attributes_for :services, allow_destroy: true
125
123
 
126
- scope :minor, where(:age.lt => 18)
127
- scope :without_ssn, without(:ssn)
124
+ scope :minor, ->{ where(:age.lt => 18) }
125
+ scope :without_ssn, ->{ without(:ssn) }
128
126
  scope :search, ->(query){ any_of({ title: query }) }
129
127
 
130
128
  def score_with_rescoring=(score)
@@ -6,13 +6,13 @@ class Player
6
6
  field :impressions, type: Integer, default: 0
7
7
  field :status
8
8
 
9
- scope :active, where(active: true) do
9
+ scope :active, ->{ where(active: true) } do
10
10
  def extension
11
11
  "extension"
12
12
  end
13
13
  end
14
14
 
15
- scope :inactive, where(active: false)
15
+ scope :inactive, ->{ where(active: false) }
16
16
  scope :frags_over, ->(count) { where(:frags.gt => count) }
17
17
  scope :deaths_under, ->(count) { where(:deaths.lt => count) }
18
18
  scope :deaths_over, ->(count) { where(:deaths.gt => count) }
@@ -13,8 +13,8 @@ class Post
13
13
  has_and_belongs_to_many :tags, before_add: :before_add_tag, after_add: :after_add_tag, before_remove: :before_remove_tag, after_remove: :after_remove_tag
14
14
  has_many :videos, validate: false
15
15
 
16
- scope :recent, where(created_at: { "$lt" => Time.now, "$gt" => 30.days.ago })
17
- scope :posting, where(:content.in => [ "Posting" ])
16
+ scope :recent, ->{ where(created_at: { "$lt" => Time.now, "$gt" => 30.days.ago }) }
17
+ scope :posting, ->{ where(:content.in => [ "Posting" ]) }
18
18
 
19
19
  validates_format_of :title, without: /\$\$\$/
20
20
 
@@ -5,5 +5,5 @@ class Preference
5
5
  field :ranking, type: Integer
6
6
  has_and_belongs_to_many :people, validate: false
7
7
  validates_length_of :name, minimum: 2, allow_nil: true
8
- scope :posting, where(:value.in => [ "Posting" ])
8
+ scope :posting, ->{ where(:value.in => [ "Posting" ]) }
9
9
  end
@@ -4,7 +4,4 @@ class Quiz
4
4
  field :name, type: String
5
5
  field :topic, type: String
6
6
  embeds_many :pages
7
-
8
- attr_accessible :topic, as: [ :default, :admin ]
9
- attr_accessible :name, as: :default
10
7
  end
@@ -1,4 +1,4 @@
1
1
  class Registry
2
2
  include Mongoid::Document
3
- field :data, type: Moped::BSON::Binary
3
+ field :data, type: BSON::Binary
4
4
  end
@@ -2,5 +2,5 @@ class Symptom
2
2
  include Mongoid::Document
3
3
  field :name, type: String
4
4
  embedded_in :person
5
- default_scope asc(:name)
5
+ default_scope ->{ asc(:name) }
6
6
  end
@@ -5,5 +5,5 @@ class Tree
5
5
  field :evergreen, type: Boolean
6
6
 
7
7
  scope :verdant, where(evergreen: true)
8
- default_scope asc(:name)
8
+ default_scope ->{ asc(:name) }
9
9
  end
@@ -9,9 +9,5 @@ class Video
9
9
  belongs_to :post
10
10
  belongs_to :game
11
11
 
12
- default_scope asc(:title)
13
-
14
- attr_accessible :title, as: [ :default, :admin ]
15
- attr_accessible :year, as: [ :default ]
16
- attr_accessible :person_attributes, as: [ :default ]
12
+ default_scope ->{ asc(:title) }
17
13
  end
@@ -9,8 +9,6 @@ class WikiPage
9
9
  field :description, type: String, localize: true
10
10
  max_versions 5
11
11
 
12
- attr_protected :author
13
-
14
12
  has_many :comments, dependent: :destroy, validate: false
15
13
  has_many :child_pages, class_name: "WikiPage", dependent: :delete, inverse_of: :parent_pages
16
14
  belongs_to :parent_pages, class_name: "WikiPage", inverse_of: :child_pages
@@ -4,8 +4,6 @@ test:
4
4
  database: mongoid_test
5
5
  hosts:
6
6
  - <%=ENV["MONGOID_SPEC_HOST"]%>:<%=ENV["MONGOID_SPEC_PORT"]%>
7
- options:
8
- consistency: :strong
9
7
  mongohq_single:
10
8
  database: <%=ENV["MONGOHQ_SINGLE_NAME"]%>
11
9
  username: <%=ENV["MONGOHQ_SINGLE_USER"]%>
@@ -14,7 +12,6 @@ test:
14
12
  - <%=ENV["MONGOHQ_SINGLE_URL"]%>
15
13
  options:
16
14
  safe: true
17
- consistency: :strong
18
15
  mongohq_repl:
19
16
  database: <%=ENV["MONGOHQ_REPL_NAME"]%>
20
17
  username: <%=ENV["MONGOHQ_REPL_USER"]%>
@@ -23,13 +20,11 @@ test:
23
20
  - <%=ENV["MONGOHQ_REPL_1_URL"]%>
24
21
  - <%=ENV["MONGOHQ_REPL_2_URL"]%>
25
22
  options:
26
- consistency: :strong
27
23
  safe: true
28
24
  mongohq_repl_uri:
29
25
  uri: <%= ENV["MONGOHQ_REPL_URI"]%>
30
26
  options:
31
27
  allow_dynamic_fields: true
32
- identity_map_enabled: false
33
28
  include_root_in_json: false
34
29
  include_type_for_serialization: false
35
30
  preload_models: false
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Errors::VersioningNotOnRoot do
4
+
5
+ describe "#message" do
6
+
7
+ let(:error) do
8
+ described_class.new(Address)
9
+ end
10
+
11
+ it "contains the problem in the message" do
12
+ error.message.should include(
13
+ "Versioning not allowed on embedded document: Address."
14
+ )
15
+ end
16
+
17
+ it "contains the summary in the message" do
18
+ error.message.should include(
19
+ "Mongoid::Versioning behaviour is only allowed on documents"
20
+ )
21
+ end
22
+
23
+ it "contains the resolution in the message" do
24
+ error.message.should include(
25
+ "Remove the versioning from the embedded Address"
26
+ )
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Relations::Macros do
4
+ describe ".embedded_in" do
5
+ context "when the document is versioned" do
6
+ it "raises an error" do
7
+ expect {
8
+ Class.new do
9
+ include Mongoid::Document
10
+ include Mongoid::Versioning
11
+ embedded_in :parent_class
12
+ end
13
+ }.to raise_error(Mongoid::Errors::VersioningNotOnRoot)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+
3
+ describe Mongoid::Relations::Metadata do
4
+ describe "#versioned?" do
5
+
6
+ context "when versioned is true" do
7
+
8
+ let(:metadata) do
9
+ described_class.new(
10
+ name: :versions,
11
+ relation: Mongoid::Relations::Embedded::Many,
12
+ versioned: true
13
+ )
14
+ end
15
+
16
+ it "returns true" do
17
+ metadata.should be_versioned
18
+ end
19
+ end
20
+
21
+ context "when versioned is false" do
22
+
23
+ let(:metadata) do
24
+ described_class.new(
25
+ name: :versions,
26
+ relation: Mongoid::Relations::Embedded::Many,
27
+ versioned: false
28
+ )
29
+ end
30
+
31
+ it "returns false" do
32
+ metadata.should_not be_versioned
33
+ end
34
+ end
35
+
36
+ context "when versioned is nil" do
37
+
38
+ let(:metadata) do
39
+ described_class.new(
40
+ name: :versions,
41
+ relation: Mongoid::Relations::Embedded::Many
42
+ )
43
+ end
44
+
45
+ it "returns false" do
46
+ metadata.should_not be_versioned
47
+ end
48
+ end
49
+ end
50
+ end