README.md in mongoid-rspec-3.0.0 vs README.md in mongoid-rspec-4.0.0

- old
+ new

@@ -1,70 +1,238 @@ -# [mongoid-rspec] +# [mongoid-rspec](https://github.com/mongoid/mongoid-rspec "A collection of RSpec-compatible matchers that help to test Mongoid documents.") -[![Build Status][travis_badge]][travis] -[![Gem Version][rubygems_badge]][rubygems] -[![Code Climate][codeclimate_badge]][codeclimate] +[![Build Status](https://travis-ci.org/mongoid/mongoid-rspec.svg?branch=master)](https://travis-ci.org/mongoid/mongoid-rspec) +[![Gem Version](https://badge.fury.io/rb/mongoid-rspec.svg)](https://badge.fury.io/rb/mongoid-rspec) -mongoid-rspec provides a collection of RSpec-compatible matchers that help to test Mongoid documents. +The mongoid-rspec library provides a collection of RSpec-compatible matchers that help to test Mongoid documents. ## Installation -### With Mongoid 5.x +Drop this line into your Gemfile: -Use mongoid-rspec [3.0.0][mongoid5] +```ruby +group :test do + gem 'mongoid-rspec' +end - gem 'mongoid-rspec', '3.0.0' +``` -### With Mongoid 4.x +## Compatibility -Use mongoid-rspec [2.1.0][mongoid4] +This gem is compatible with Mongoid 3, 4, 5 and 6. - gem 'mongoid-rspec', '~> 2.1.0' +## Configuration -### With Mongoid 3.x +### Rails -Use mongoid-rspec [1.13.0][mongoid3]. +Add to your `rails_helper.rb` file - gem 'mongoid-rspec', '~> 1.13.0' +```ruby +require 'mongoid-rspec' -### With Mongoid 2.x +RSpec.configure do |config| + config.include Mongoid::Matchers, type: :model +end +``` -Use mongoid-rspec [1.4.5][mongoid2] +### Other - gem 'mongoid-rspec', '1.4.5' +Add to your `spec_helper.rb` file. -### Configuring +```ruby +require 'mongoid-rspec' -Drop in existing or dedicated support file in spec/support. -i.e: `spec/support/mongoid.rb` +RSpec.configure do |config| + config.include Mongoid::Matchers +end +``` +## Matchers + +### be_mongoid_document + ```ruby -RSpec.configure do |config| - config.include Mongoid::Matchers, type: :model +class Post + include Mongoid::Document end + +RSpec.describe Post, type: :model do + it { is_expected.to be_mongoid_document } +end ``` -If you aren't using rails then you don't have to specify the type. -If you want to know why visit [the rspec documentation](https://relishapp.com/rspec/rspec-rails/docs/directory-structure). +### be_dynamic_document -## Matchers +```ruby +class User + include Mongoid::Document + include Mongoid::Attributes::Dynamic +end +RSpec.describe User, type: :model do + it { is_expected.to be_dynamic_document } +end +``` + +### have_timestamps + +With full timestamps. + +```ruby +class Log + include Mongoid::Document + include Mongoid::Timestamps +end + +RSpec.describe Log, type: :model do + it { is_expected.to have_timestamps } +end +``` + +With short timestamps. + +```ruby +class User + include Mongoid::Document + include Mongoid::Timestamps::Short +end + +RSpec.describe User, type: :model do + it { is_expected.to have_timestamps.shortened } +end +``` + +With only creating or updating timestamps. + +```ruby +class Admin + include Mongoid::Document + include Mongoid::Timestamps::Create + include Mongoid::Timestamps::Update +end + +RSpec.describe Admin, type: :model do + it { is_expected.to have_timestamps.for(:creating) } + it { is_expected.to have_timestamps.for(:updating) } +end +``` + +With short creating or updating timestamps. + +```ruby +class Post + include Mongoid::Document + include Mongoid::Timestamps::Create::Short +end + +RSpec.describe Short, type: :model do + it { is_expected.to have_timestamps.for(:creating).shortened } +end +``` + +### be_stored_in + +```ruby +class Post + include Mongoid::Document + + store_in database: 'db1', collection: 'messages', client: 'secondary' +end + +RSpec.describe Post, type: :model do + it { is_expected.to be_stored_in(database: 'db1', collection: 'messages', client: 'secondary') } +end +``` + +It checks only those options, that you specify. For instance, test in example below will pass, even though expectation contains only `database` option. + +```ruby +class Comment + include Mongoid::Document + + store_in database: 'db2', collection: 'messages' +end + +RSpec.describe Comment, type: :model do + it { is_expected.to be_stored_in(database: 'db2') } +end +``` + +It works fine with lambdas and procs. + +```ruby +class User + include Mongoid::Document + + store_in database: ->{ Thread.current[:database] } +end + +RSpec.describe Post, type: :model do + it do + Thread.current[:database] = 'db3' + is_expected.to be_stored_in(database: 'db3') + + Thread.current[:database] = 'db4' + is_expected.to be_stored_in(database: 'db4') + end +end +``` + +### have_index_for + +```ruby +class Article + index({ title: 1 }, { unique: true, background: true, drop_dups: true }) + index({ title: 1, created_at: -1 }) + index({ category: 1 }) +end + +RSpec.describe Article, type: :model do + it do + is_expected + .to have_index_for(title: 1) + .with_options(unique: true, background: true, drop_dups: true) + end + it { is_expected.to have_index_for(title: 1, created_at: -1) } + it { is_expected.to have_index_for(category: 1) } +end +``` + +### Field Matchers + +```ruby +RSpec.describe Article do + it { is_expected.to have_field(:published).of_type(Boolean).with_default_value_of(false) } + it { is_expected.to have_field(:allow_comments).of_type(Boolean).with_default_value_of(true) } + it { is_expected.not_to have_field(:allow_comments).of_type(Boolean).with_default_value_of(false) } + it { is_expected.not_to have_field(:number_of_comments).of_type(Integer).with_default_value_of(1) } +end + +RSpec.describe User do + it { is_expected.to have_fields(:email, :login) } + it { is_expected.to have_field(:s).with_alias(:status) } + it { is_expected.to have_fields(:birthdate, :registered_at).of_type(DateTime) } +end +``` + ### Association Matchers ```ruby RSpec.describe User do it { is_expected.to have_many(:articles).with_foreign_key(:author_id).ordered_by(:title) } it { is_expected.to have_one(:record) } - #can verify autobuild is set to true + + # can verify autobuild is set to true it { is_expected.to have_one(:record).with_autobuild } it { is_expected.to have_many :comments } - #can also specify with_dependent to test if :dependent => :destroy/:destroy_all/:delete is set + # can also specify with_dependent to test if :dependent => :destroy/:destroy_all/:delete is set it { is_expected.to have_many(:comments).with_dependent(:destroy) } - #can verify autosave is set to true + + # can verify autosave is set to true it { is_expected.to have_many(:comments).with_autosave } it { is_expected.to embed_one :profile } it { is_expected.to have_and_belong_to_many(:children) } @@ -93,25 +261,10 @@ RSpec.describe Site do it { is_expected.to have_many(:users).as_inverse_of(:site).ordered_by(:email.asc).with_counter_cache } end ``` -### Mass Assignment Matcher - -```ruby -RSpec.describe User do - it { is_expected.to allow_mass_assignment_of(:login) } - it { is_expected.to allow_mass_assignment_of(:email) } - it { is_expected.to allow_mass_assignment_of(:age) } - it { is_expected.to allow_mass_assignment_of(:password) } - it { is_expected.to allow_mass_assignment_of(:password) } - it { is_expected.to allow_mass_assignment_of(:role).as(:admin) } - - it { is_expected.not_to allow_mass_assignment_of(:role) } -end -``` - ### Validation Matchers ```ruby RSpec.describe Site do it { is_expected.to validate_presence_of(:name) } @@ -137,10 +290,14 @@ RSpec.describe Article do it { is_expected.to validate_length_of(:title).within(8..16) } end +RSpec.describe Visitor do + it { is_expected.to validate_length_of(:name).with_maximum(160).with_minimum(1) } +end + RSpec.describe Profile do it { is_expected.to validate_numericality_of(:age).greater_than(0) } end RSpec.describe MovieArticle do @@ -153,93 +310,42 @@ # should redefine the kind method to return :custom, i.e. "def self.kind() :custom end" it { is_expected.to custom_validate(:ssn).with_validator(SsnValidator) } end ``` -### Accepts Nested Attributes Matcher +### Mass Assignment Matcher ```ruby RSpec.describe User do - it { is_expected.to accept_nested_attributes_for(:articles) } - it { is_expected.to accept_nested_attributes_for(:comments) } -end + it { is_expected.to allow_mass_assignment_of(:login) } + it { is_expected.to allow_mass_assignment_of(:email) } + it { is_expected.to allow_mass_assignment_of(:age) } + it { is_expected.to allow_mass_assignment_of(:password) } + it { is_expected.to allow_mass_assignment_of(:password) } + it { is_expected.to allow_mass_assignment_of(:role).as(:admin) } -RSpec.describe Article do - it { is_expected.to accept_nested_attributes_for(:permalink) } + it { is_expected.not_to allow_mass_assignment_of(:role) } end ``` -### Index Matcher +### Accepts Nested Attributes Matcher ```ruby -RSpec.describe Article do - it { is_expected.to have_index_for(published: 1) } - it { is_expected.to have_index_for(title: 1).with_options(unique: true, background: true) } -end - -RSpec.describe Profile do - it { is_expected.to have_index_for(first_name: 1, last_name: 1) } -end - -Rspec.describe Log do - it { is_expected.to have_index_for(created_at: 1).with_options(bucket_size: 100, expire_after_seconds: 3600) } -end -``` - -### Others - -```ruby RSpec.describe User do - it { is_expected.to have_fields(:email, :login) } - it { is_expected.to have_field(:s).with_alias(:status) } - it { is_expected.to have_fields(:birthdate, :registered_at).of_type(DateTime) } - - # if you're declaring 'include Mongoid::Timestamps' - # or any of 'include Mongoid::Timestamps::Created' and 'Mongoid::Timestamps::Updated' - it { is_expected.to be_timestamped_document } - it { is_expected.to be_timestamped_document.with(:created) } - it { is_expected.not_to be_timestamped_document.with(:updated) } - - it { is_expected.to be_versioned_document } # if you're declaring `include Mongoid::Versioning` - it { is_expected.to be_paranoid_document } # if you're declaring `include Mongoid::Paranoia` - it { is_expected.to be_multiparameted_document } # if you're declaring `include Mongoid::MultiParameterAttributes` + it { is_expected.to accept_nested_attributes_for(:articles) } + it { is_expected.to accept_nested_attributes_for(:comments) } end -RSpec.describe Log do - it { is_expected.to be_stored_in :logs } - it { is_expected.to be_dynamic_document } -end - RSpec.describe Article do - it { is_expected.to have_field(:published).of_type(Boolean).with_default_value_of(false) } - it { is_expected.to have_field(:allow_comments).of_type(Boolean).with_default_value_of(true) } - it { is_expected.not_to have_field(:allow_comments).of_type(Boolean).with_default_value_of(false) } - it { is_expected.not_to have_field(:number_of_comments).of_type(Integer).with_default_value_of(1) } + it { is_expected.to accept_nested_attributes_for(:permalink) } end ``` -## Known issues +## Contributing -accept_nested_attributes_for matcher must test options [issue 91](https://github.com/mongoid-rspec/mongoid-rspec/issues/91). +You're encouraged to contribute to this library. See [CONTRIBUTING](CONTRIBUTING.md) for details. -## Acknowledgement +## Copyright and License -Thanks to [Durran Jordan][durran] for providing the changes necessary to make -this compatible with mongoid 2.0.0.rc, and for other [contributors](https://github.com/mongoid-rspec/mongoid-rspec/contributors) -to this project. +Copyright (c) 2009-2018 Evan Sagge and Contributors. -[mongoid-rspec]: https://github.com/mongoid-rspec/mongoid-rspec "A collection of RSpec-compatible matchers that help to test Mongoid documents." - -[durran]: https://github.com/durran -[mongoid2]: https://rubygems.org/gems/mongoid-rspec/versions/1.4.5 -[mongoid3]: https://rubygems.org/gems/mongoid-rspec/versions/1.13.0 -[mongoid4]: https://rubygems.org/gems/mongoid-rspec/versions/2.1.0 -[mongoid5]: https://rubygems.org/gems/mongoid-rspec/versions/3.0.0 - -[travis_badge]: http://img.shields.io/travis/mongoid-rspec/mongoid-rspec.svg?style=flat -[travis]: https://travis-ci.org/mongoid-rspec/mongoid-rspec - -[rubygems_badge]: http://img.shields.io/gem/v/mongoid-rspec.svg?style=flat -[rubygems]: http://rubygems.org/gems/mongoid-rspec - -[codeclimate_badge]: http://img.shields.io/codeclimate/github/mongoid-rspec/mongoid-rspec.svg?style=flat -[codeclimate]: https://codeclimate.com/github/mongoid-rspec/mongoid-rspec +MIT License. See [LICENSE](LICENSE) for details.