mongoid-versioning 0.2.0 → 1.0.0.beta1

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.
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