mongo-fixture 0.0.1

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,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.pryrc ADDED
@@ -0,0 +1,12 @@
1
+ require "mongo-fixture"
2
+ DB = Mongo::Connection.new.db "mongo-fixture-cucumber"
3
+ puts "\e[34mConnection to MongoDB 'mongo-fixture-cucumber' loaded in \e[1mDB\e[0m\e[34m variable\e[0m"
4
+ puts "\e[34mTry the \e[1mDB[:visitors]\e[0m\e[34m, \e[1mDB[:aliens]\e[0m\e[34m, \e[1mDB[:visits]\e[0m\e[34m and \e[1mDB[:users]\e[0m\e[34m collections\e[0m"
5
+ @DB = DB
6
+ def self.drop *args
7
+ args.each do |coll|
8
+ @DB[coll].drop
9
+ end
10
+ end
11
+
12
+ puts "\e[34mTip: for fast collection dropping use \e[1mdrop :collection1, :collection2\e[0m"
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - rbx-18mode
9
+ - rbx-19mode
10
+ - ree
11
+ bundler_args: --without cucumber
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongo-fixture.gemspec
4
+ gemspec
5
+
6
+ group :cucumber do
7
+ gem "cucumber"
8
+ gem "bson_ext"
9
+ gem "pry"
10
+ end
11
+
12
+ group :test do
13
+ gem "rake"
14
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Xavier Via
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,102 @@
1
+ Mongo::Fixture
2
+ ===============
3
+ [![Build Status](https://secure.travis-ci.org/Fetcher/mongo-fixture.png)](http://travis-ci.org/Fetcher/mongo-fixture) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/Fetcher/mongo-fixture)
4
+
5
+ Just like Rails 2 fixtures, but for [MongoDB][mongo-db] (using the standard [mongo connector Gem][mongo-gem] ).
6
+
7
+ [mongo-db]: http://www.mongodb.org/
8
+ [mongo-gem]: http://rubygems.org/gems/mongo
9
+
10
+ Show off
11
+ ========
12
+
13
+ Assuming you have a fixture for the collection users with:
14
+ ```yaml
15
+ # test/fixtures/simple/users.yaml
16
+ john:
17
+ name: John
18
+ last_name: Doe
19
+ email: john@doe.com
20
+ jane:
21
+ name: Jane
22
+ last_name: Doe
23
+ email: jane@doe.com
24
+ ```
25
+
26
+ and for messages:
27
+ ```yaml
28
+ # test/fixtures/simple/messages.yaml
29
+ greeting:
30
+ sender_id: 1
31
+ receiver_id: 2
32
+ text: Hi Jane! Long time no see.
33
+ long_time:
34
+ sender_id: 2
35
+ receiver_id: 1
36
+ text: John! Long time indeed. How are you doing?
37
+ ```
38
+
39
+ and the ruby script
40
+
41
+ ```ruby
42
+ # script.rb
43
+ require "mongo-fixture"
44
+
45
+ DB = Mongo::Connection.new.db 'mongo-test-db' # Just a simple example
46
+
47
+ fixture = Mongo::Fixture.new :simple, DB # Will load all the data in the fixture into the database
48
+
49
+ fixture.users # == fixture[:users]
50
+ fixture.users.john.name # => "John"
51
+ # The YAML files are parsed into a SymbolMatrix
52
+ # http://github.com/Fetcher/symbolmatrix
53
+
54
+ fixture.rollback # returns users and messages to pristine status (#drop)
55
+
56
+
57
+ fixture = Mongo::Fixture.new :simple, DB, false # The `false` flag prevent the constructor to automatically push
58
+ # the fixture into the database
59
+
60
+ fixture.check # Will fail if the user or messages collection
61
+ # were already occupied with something
62
+
63
+ fixture.push # Inserts the fixture in the database
64
+
65
+ fixture.rollback # Don't forget to rollback
66
+
67
+ ```
68
+
69
+ ...naturally, `mongo-fixture` makes a lot more sense within some testing framework.
70
+
71
+ > **Note**: As of version 0.0.1, the `test/fixtures` path for fixtures is not configurable. Will solve soon.
72
+
73
+ Installation
74
+ ------------
75
+
76
+ gem install mongo-fixture
77
+
78
+ ### Or using Bundler
79
+
80
+ gem 'mongo-fixture'
81
+
82
+ And then execute:
83
+
84
+ bundle
85
+
86
+
87
+ ## License
88
+
89
+ Copyright (C) 2012 Fetcher
90
+
91
+ This program is free software: you can redistribute it and/or modify
92
+ it under the terms of the GNU General Public License as published by
93
+ the Free Software Foundation, either version 3 of the License, or
94
+ (at your option) any later version.
95
+
96
+ This program is distributed in the hope that it will be useful,
97
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
98
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
99
+ GNU General Public License for more details.
100
+
101
+ You should have received a copy of the GNU General Public License
102
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require "rspec/core/rake_task"
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.pattern = "./spec/**/*_spec.rb"
9
+ end
10
+
11
+ task :default => :spec
@@ -0,0 +1,24 @@
1
+ Feature: Configurable fixtures folder
2
+ In order to load fixtures from arbitrary folders
3
+ I want to be able to configure the source of the fixtures
4
+
5
+ Background: We have a database connection working
6
+ Given a mongo database connection
7
+
8
+ Scenario: The folder is now just "fixtures"
9
+ Given a collection users
10
+ And a file "fixtures/configurable/users.yaml" with:
11
+ """
12
+ xavi:
13
+ name: Xavier
14
+ email: xavier@via.com
15
+ john:
16
+ name: Johnny
17
+ email: john@doe.com
18
+ """
19
+ When I set the fixtures path as "fixtures"
20
+ And I load the configurable fixture
21
+ Then I should see 1 record in users with name "Xavier" and email "xavier@via.com"
22
+ And I should see 1 record in users with name "Johnny" and email "john@doe.com"
23
+ When I rollback
24
+ Then I should see 0 records in users
@@ -0,0 +1,84 @@
1
+ Feature: Play around with Fixtures
2
+ In order to test if Mongo::Fixture is really practical
3
+ As the gem developer
4
+ I want to play around with it a little bit
5
+
6
+ Background: We have a database connection working
7
+ Given a mongo database connection
8
+
9
+ Scenario: Create a simple fixture, push it and rollback
10
+ Given a collection visitors
11
+ And a collection aliens
12
+ And a collection visits
13
+ And a file "test/fixtures/simple/visitors.yaml" with:
14
+ """
15
+ anonymous:
16
+ name: V
17
+ email: v@for.vendetta
18
+ """
19
+ And a file "test/fixtures/simple/aliens.yaml" with:
20
+ """
21
+ yourfavouritemartian:
22
+ race: Zerg
23
+ """
24
+ And a file "test/fixtures/simple/visits.yaml" with:
25
+ """
26
+ v2yfm:
27
+ alien_id: 1
28
+ visitor_id: 1
29
+ """
30
+ When I load the simple fixture
31
+ Then I should see 1 record in visitors with name "V" and email "v@for.vendetta"
32
+ And I should see 1 record in aliens with race "Zerg"
33
+ And I should see 1 record in visits with alien_id 1 and visitor_id 1
34
+ When I rollback
35
+ Then I should see 0 records in visitors
36
+ And I should see 0 records in aliens
37
+ And I should see 0 records in visits
38
+
39
+ Scenario: The users collection has a password field
40
+ Given a collection users
41
+ And a file "test/fixtures/password/users.yaml" with:
42
+ """
43
+ john:
44
+ name: John Wayne
45
+ password:
46
+ raw: secret
47
+ processed: 5bfb52c459cdb07218c176b5ddec9b6215bd5b76
48
+ """
49
+ When I load the password fixture
50
+ Then I should see 1 record in users with name "John Wayne" and password "5bfb52c459cdb07218c176b5ddec9b6215bd5b76"
51
+ When I rollback
52
+ Then I should see 0 records in users
53
+
54
+ Scenario: Misconfigured password field
55
+ Given a collection users
56
+ And a file "test/fixtures/misconfigured/users.yaml" with:
57
+ """
58
+ good_entry:
59
+ password:
60
+ raw: secret
61
+ processed: 96bdg756n5sgf9gfs==
62
+ wrong_entry:
63
+ password:
64
+ missing: The field
65
+ """
66
+ Then the loading of misconfigured fixture should fail
67
+ And I should see that the collection was "users"
68
+ And I should see that the field was "password"
69
+ And I should see that the entry was "wrong_entry"
70
+ And I should see 0 records in users
71
+
72
+ Scenario: I save the done fixtures so to perform the rollbacks later
73
+ Given a collection users
74
+ And a file "test/fixtures/password/users.yaml" with:
75
+ """
76
+ john:
77
+ name: John
78
+ last_name: Wayne
79
+ """
80
+ And I load the password fixture
81
+ Then I should see 1 record in users with name "John" and last_name "Wayne"
82
+ When I stash the fixture as done
83
+ And I rollback the stashed fixtures
84
+ Then I should see 0 records in users
@@ -0,0 +1,11 @@
1
+ # Feature: Play around with Fixtures
2
+ # In order to test if Mongo::Fixture is really practical
3
+ # As the gem developer
4
+ # I want to play around with it a little bit
5
+ #
6
+ # Background: We have a database connection working
7
+ # Given a mongo database connection
8
+
9
+ Given /^a mongo database connection$/ do
10
+ @DB = Mongo::Connection.new.db "mongo-fixture-cucumber"
11
+ end
@@ -0,0 +1,69 @@
1
+ #Scenario: Create a simple fixture, push it and rollback
2
+ # Given a collection visitors
3
+ # And a collection aliens
4
+ # And a collection visits
5
+ # And a file "test/fixtures/simple/visitors.yaml" with:
6
+ # """
7
+ # anonymous:
8
+ # name: V
9
+ # email: v@for.vendetta
10
+ # """
11
+ # And a file "test/fixtures/simple/aliens.yaml" with:
12
+ # """
13
+ # yourfavouritemartian:
14
+ # race: Zerg
15
+ # """
16
+ # And a file "test/fixtures/simple/visits.yaml" with:
17
+ # """
18
+ # v2yfm:
19
+ # alien_id: 1
20
+ # visitor_id: 1
21
+ # """
22
+ # When I load the simple fixture
23
+ # Then I should see 1 record in visitors with name "V" and email "v@for.vendetta"
24
+ # And I should see 1 record in aliens with race "Zerg"
25
+ # And I should see 1 record in visits with alien_id 1 and visitor_id 1
26
+ # When I rollback
27
+ # Then I should see 0 records in visitors
28
+ # And I should see 0 records in aliens
29
+ # And I should see 0 records in visits
30
+
31
+ Given /^a collection (\w+)$/ do |collection|
32
+ @DB[collection]
33
+ end
34
+
35
+ And /^a file "(.+?)" with:$/ do |file, content|
36
+ Fast.file.write file, content
37
+ end
38
+
39
+ When /^I load the (\w+) fixture$/ do |fixture|
40
+ # binding.pry
41
+ @fixture = Mongo::Fixture.new fixture.to_sym, @DB
42
+ end
43
+
44
+ Then /^I should see (\d+) record in (\w+) with (\w+) "([^"]+)" and (\w+) "(.+?)"$/ do
45
+ |amount, collection, field1, data1, field2, data2|
46
+
47
+ @DB[collection].find( field1 => data1, field2 => data2 ).count.should == amount.to_i
48
+ end
49
+
50
+ And /^I should see (\d+) record in (\w+) with (\w+) "([^"]+)"$/ do
51
+ |amount, collection, field, data|
52
+
53
+ @DB[collection].find( field => data ).count.should == amount.to_i
54
+ end
55
+
56
+ Then /^I should see (\d+) record in (\w+) with (\w+) (\d+) and (\w+) (\d+)$/ do
57
+ |amount, collection, field1, data1, field2, data2|
58
+
59
+ @DB[collection].find( field1 => data1.to_i, field2 => data2.to_i ).count.should == amount.to_i
60
+ end
61
+
62
+ When /^I rollback$/ do
63
+ @fixture.rollback
64
+ end
65
+
66
+ Then /^I should see (\d+) records in (\w+)$/ do |amount, collection|
67
+ @DB[collection].count.should == amount.to_i
68
+ end
69
+
@@ -0,0 +1,40 @@
1
+ #Scenario: Misconfigured password field
2
+ # Given a collection users
3
+ # And a file "test/fixtures/misconfigured/users.yaml" with:
4
+ # """
5
+ # good_entry:
6
+ # password:
7
+ # raw: secret
8
+ # processed: 96bdg756n5sgf9gfs==
9
+ # wrong_entry:
10
+ # password:
11
+ # missing: The field
12
+ # """
13
+ # Then the loading of misconfigured fixture should fail
14
+ # And I should see that the collection was "users"
15
+ # And I should see that the field was "password"
16
+ # And I should see that the entry was "wrong_entry"
17
+ # And I should see 0 records in users
18
+
19
+ # NOTE: most steps have been defined in
20
+ # `create_a_simple_fixture_push_it_and_rollback.rb`
21
+
22
+ Then /^the loading of (\w+) fixture should fail$/ do |fixture|
23
+ begin
24
+ Mongo::Fixture.new fixture.to_sym, @DB
25
+ rescue Mongo::Fixture::MissingProcessedValueError => e
26
+ @exception = e
27
+ end
28
+ end
29
+
30
+ And /^I should see that the collection was "(\w+)"$/ do |collection|
31
+ @exception.message.should include collection
32
+ end
33
+
34
+ And /^I should see that the field was "(\w+)"$/ do |field|
35
+ @exception.message.should include field
36
+ end
37
+
38
+ And /^I should see that the entry was "(\w+)"$/ do |entry|
39
+ @exception.message.should include entry
40
+ end
@@ -0,0 +1,6 @@
1
+ require "fast"
2
+ require "pry"
3
+
4
+ $LOAD_PATH << File.expand_path("../../../../lib", __FILE__)
5
+
6
+ require "mongo-fixture"
@@ -0,0 +1,6 @@
1
+ After do
2
+ [:visitors, :aliens, :visits, :users].each do |collection|
3
+ @DB[collection].drop
4
+ end
5
+ Fast.dir.remove! :test, :fixtures
6
+ end
@@ -0,0 +1,149 @@
1
+ # Third-party
2
+ require "fast/fast"
3
+ require "symbolmatrix"
4
+ require "mongo"
5
+
6
+ require "mongo-fixture/version"
7
+
8
+ module Mongo
9
+
10
+ # Fixture managing class for MongoDB
11
+ class Fixture
12
+ ## Class methods
13
+
14
+ # Returns the current path to the fixtures folder
15
+ def self.path
16
+ @@path ||= "test/fixtures"
17
+ end
18
+
19
+ ## Instance methods
20
+
21
+ # Initializes the fixture handler
22
+ # Accepts optionally a symbol as a reference to the fixture
23
+ # and a Mongo::DB connection
24
+ def initialize fixture = nil, connection = nil, option_push = true
25
+ load fixture if fixture
26
+
27
+ @connection = connection if connection
28
+ push if fixture && connection && option_push
29
+ end
30
+
31
+ # Loads the fixture files into this instance
32
+ def load fixture
33
+ raise LoadingFixtureIllegal, "A check has already been made, loading a different fixture is illegal" if @checked
34
+
35
+ Fast.dir("#{fixtures_path}/#{fixture}").files.to.symbols.each do |file|
36
+ @data ||= {}
37
+ @data[file] = SymbolMatrix.new "#{fixtures_path}/#{fixture}/#{file}.yaml"
38
+ end
39
+ end
40
+
41
+ # Returns the current fixtures path where Sequel::Fixtures looks for fixture folders
42
+ def fixtures_path
43
+ Mongo::Fixture.path
44
+ end
45
+
46
+ # Forces the check to pass. Dangerous!
47
+ def force_checked!
48
+ @checked = true
49
+ end
50
+
51
+ # Returns the SymbolMatrix with the data referring to that table
52
+ def [] reference
53
+ @data[reference]
54
+ end
55
+
56
+ # Method missing, for enabling discovery of tables
57
+ def method_missing s, *args
58
+ return @data[s] if @data && @data.has_key?(s)
59
+ return super
60
+ end
61
+
62
+ # Returns the current database connection
63
+ attr_reader :connection
64
+
65
+ # Sets the connection. Raises an ChangingConnectionIllegal exception if this fixture has already been checked
66
+ def connection= the_connection
67
+ raise ChangingConnectionIllegal, "A check has already been performed, changing the connection now is illegal" if @checked
68
+ @connection = the_connection
69
+ end
70
+
71
+ # Returns the current data collection
72
+ attr_reader :data
73
+
74
+ # Assures that the collections are empty before proceeding
75
+ def check
76
+ return @checked if @checked # If already checked, it's alright
77
+
78
+ raise MissingFixtureError, "No fixture has been loaded, nothing to check" unless @data
79
+ raise MissingConnectionError, "No connection has been provided, impossible to check" unless @connection
80
+
81
+ @data.each_key do |collection|
82
+ raise CollectionsNotEmptyError, "The collection '#{collection}' is not empty, all collections should be empty prior to testing" if @connection[collection].count != 0
83
+ end
84
+ return @checked = true
85
+ end
86
+
87
+ # Inserts the fixture data into the corresponding collections
88
+ def push
89
+ check
90
+
91
+ @data.each do |collection, matrix|
92
+ matrix.each do |element, values|
93
+ begin
94
+ @connection[collection].insert simplify values.to_hash
95
+ rescue MissingProcessedValueError => m
96
+ rollback
97
+ raise MissingProcessedValueError, "In record '#{element}' to be inserted into '#{collection}', the processed value of field '#{m.field}' is missing, aborting"
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ # Simplifies the hash in order to insert it into the database
104
+ # (Note: I'm well aware that this functionality belongs in a dependency,
105
+ # specially now that is repeated here and in Sequel::Fixture)
106
+ # @param [Hash] the hash to be processed
107
+ def simplify the_hash
108
+ the_returned_hash = {}
109
+ the_hash.each do |key, value|
110
+ if value.is_a? Hash
111
+ unless value.has_key? :processed
112
+ raise MissingProcessedValueError.new "The processed value to insert into the db is missing from the field '#{key}', aborting", key
113
+ end
114
+ the_returned_hash[key] = value[:processed]
115
+ else
116
+ the_returned_hash[key] = value
117
+ end
118
+ end
119
+ return the_returned_hash
120
+ end
121
+
122
+ # Empties the collections, only if they were empty to begin with
123
+ def rollback
124
+ begin
125
+ check
126
+
127
+ @data.each_key do |collection|
128
+ @connection[collection].drop
129
+ end
130
+ rescue CollectionsNotEmptyError => e
131
+ raise RollbackIllegalError, "The collections weren't empty to begin with, rollback aborted."
132
+ end
133
+ end
134
+
135
+ class LoadingFixtureIllegal < StandardError; end
136
+ class CollectionsNotEmptyError < StandardError; end
137
+ class MissingFixtureError < StandardError; end
138
+ class MissingConnectionError < StandardError; end
139
+ class ChangingConnectionIllegal < StandardError; end
140
+ class RollbackIllegalError < StandardError; end
141
+ class MissingProcessedValueError < StandardError
142
+ attr_accessor :field
143
+ def initialize message, field = nil
144
+ @field = field
145
+ super message
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,5 @@
1
+ module Mongo
2
+ class Fixture
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mongo-fixture/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Xavier Via"]
6
+ gem.email = ["xavier.via.canel@gmail.com"]
7
+ gem.description = %q{Flexible fixtures for the MongoDB Gem inspired in Rails 2 fixtures}
8
+ gem.summary = %q{Flexible fixtures for the MongoDB Gem inspired in Rails 2 fixtures}
9
+ gem.homepage = "http://github.com/Fetcher/mongo-fixture"
10
+
11
+ gem.add_dependency "mongo"
12
+ gem.add_dependency "fast"
13
+ gem.add_dependency "symbolmatrix"
14
+
15
+ gem.add_development_dependency "rspec"
16
+
17
+ gem.files = `git ls-files`.split($\)
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.name = "mongo-fixture"
21
+ gem.require_paths = ["lib"]
22
+ gem.version = Mongo::Fixture::VERSION
23
+ end
@@ -0,0 +1,523 @@
1
+ require "mongo-fixture"
2
+
3
+ describe Mongo::Fixture do
4
+ describe ".path" do
5
+ it "should return 'test/fixtures'" do
6
+ Mongo::Fixture.path.should == "test/fixtures"
7
+ end
8
+ end
9
+
10
+ describe ".new" do
11
+ context "a symbol is sent representing a fixture" do
12
+ it "should call load" do
13
+ Mongo::Fixture.any_instance.should_receive(:load).with :test
14
+ Mongo::Fixture.new :test
15
+ end
16
+ end
17
+
18
+ context "a database connection is passed" do
19
+ it "should call push" do
20
+ database = double 'mongodb'
21
+ Mongo::Fixture.any_instance.stub :load
22
+ Mongo::Fixture.any_instance.should_receive :push
23
+ Mongo::Fixture.new :test, database
24
+ end
25
+ end
26
+
27
+ context "a database is provided but no fixture" do
28
+ it "should not call push" do
29
+ database = double 'database'
30
+ Mongo::Fixture.any_instance.should_not_receive :push
31
+ Mongo::Fixture.new nil, database
32
+ end
33
+ end
34
+
35
+ context "a database connection and a valid fixture are passed but a false flag is passed at the end" do
36
+ it "should not push" do
37
+ database = double 'database'
38
+ Mongo::Fixture.any_instance.stub :load
39
+ Mongo::Fixture.any_instance.should_not_receive :push
40
+ Mongo::Fixture.new :test, database, false
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#load" do
46
+ context "there is a valid fixture folder setup" do
47
+ before do
48
+ Fast.file! "test/fixtures/test/users.yaml"
49
+ Fast.file! "test/fixtures/test/actions.yaml"
50
+ end
51
+
52
+ it "should load the fixture YAML files using SymbolMatrix (third-party)" do
53
+ fix = Mongo::Fixture.new
54
+ fix.stub :check
55
+ SymbolMatrix.should_receive(:new).with "test/fixtures/test/users.yaml"
56
+ SymbolMatrix.should_receive(:new).with "test/fixtures/test/actions.yaml"
57
+ fix.load :test
58
+ end
59
+
60
+ after do
61
+ Fast.dir.remove! :test
62
+ end
63
+ end
64
+
65
+ context "the check has been performed and I attempt to load another fixture" do
66
+ before do
67
+ Fast.file.write "test/fixtures/test/users.yaml", "john: { name: John Doe }"
68
+ Fast.file.write "test/fixtures/another/users.yaml", "john: { name: John Doe }"
69
+ end
70
+
71
+ it "should fail" do
72
+ Mongo::Fixture.any_instance.stub :push
73
+ database = double 'database'
74
+ database.stub(:[]).and_return double(:count => 0 )
75
+ fix = Mongo::Fixture.new :test, database
76
+ fix.check
77
+ expect { fix.load :another
78
+ }.to raise_error Mongo::Fixture::LoadingFixtureIllegal,
79
+ "A check has already been made, loading a different fixture is illegal"
80
+ end
81
+
82
+ after do
83
+ Fast.dir.remove! :test
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "#force_checked!" do
89
+ it "check should return true and should not call [] in the passed database" do
90
+ database = stub 'database'
91
+ database.should_not_receive :[]
92
+
93
+ Mongo::Fixture.any_instance.stub :load
94
+ fix = Mongo::Fixture.new :anything, database, false
95
+ fix.force_checked!.should === true
96
+ fix.check.should === true
97
+ end
98
+ end
99
+
100
+ describe "#[]" do
101
+ context "a valid fixture has been loaded" do
102
+ before do
103
+ Fast.file.write "test/fixtures/test/users.yaml", "john: { name: John, last_name: Wayne }"
104
+ Fast.file.write "test/fixtures/test/actions.yaml", "walk: { user_id: 1, action: Walks }"
105
+ @fix = Mongo::Fixture.new
106
+ @fix.stub :check
107
+ @fix.load :test
108
+ end
109
+
110
+ context "a collection key is passed" do
111
+ it "should return the SymbolMatrix containing the same info as in the matching YAML file" do
112
+ @fix[:users].should be_a SymbolMatrix
113
+ @fix[:users].john.name.should == "John"
114
+ @fix[:users].john.last_name.should == "Wayne"
115
+
116
+ @fix[:actions].walk.action.should == "Walks"
117
+ end
118
+ end
119
+
120
+ after do
121
+ Fast.dir.remove! :test
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#method_missing" do
127
+ context "a valid fixture has been loaded" do
128
+ context "a collection key is passed" do
129
+ before do
130
+ Fast.file.write "test/fixtures/test/users.yaml", "john: { name: John, last_name: Wayne }"
131
+ Fast.file.write "test/fixtures/test/actions.yaml", "walk: { user_id: 1, action: Walks }"
132
+ @fix = Mongo::Fixture.new
133
+ @fix.stub :check
134
+ @fix.load :test
135
+ end
136
+
137
+ it "should return the SymbolMatrix containing the same info as in the matching YAML file" do
138
+ @fix.users.should be_a SymbolMatrix
139
+ @fix.users.john.name.should == "John"
140
+ @fix.users.john.last_name.should == "Wayne"
141
+
142
+ @fix.actions.walk.action.should == "Walks"
143
+ end
144
+
145
+ after do
146
+ Fast.dir.remove! :test
147
+ end
148
+ end
149
+ end
150
+
151
+ it "should raise no method error if matches nothing" do
152
+ expect { Mongo::Fixture.new.nothing = "hola"
153
+ }.to raise_error NoMethodError
154
+ end
155
+ end
156
+
157
+ describe "#fixtures_path" do
158
+ it "should call Mongo::Fixture.path" do
159
+ Mongo::Fixture.should_receive :path
160
+ Mongo::Fixture.new.fixtures_path
161
+ end
162
+ end
163
+
164
+ describe "#check" do
165
+ it "should count records on all the used collections" do
166
+ Mongo::Fixture.any_instance.stub :push # push doesn't get called
167
+
168
+ database = double 'mongodb' # Fake database connection
169
+ counter = stub # fake collection
170
+
171
+ database.should_receive(:[]).with(:users).and_return counter
172
+ database.should_receive(:[]).with(:actions).and_return counter
173
+ counter.should_receive(:count).twice.and_return 0
174
+
175
+ fix = Mongo::Fixture.new nil, database
176
+ collections = [:users, :actions]
177
+ def fix.stub_data
178
+ @data = { :users => nil, :actions => nil }
179
+ end
180
+ fix.stub_data
181
+
182
+ fix.check
183
+ end
184
+
185
+ it "should raise error if the count is different from 0" do
186
+ database = double "mongodb"
187
+ counter = stub
188
+ counter.should_receive(:count).and_return 4
189
+ database.stub(:[]).and_return counter
190
+ Mongo::Fixture.any_instance.stub :push
191
+
192
+ fix = Mongo::Fixture.new nil, database
193
+ def fix.stub_data
194
+ @data = { :users => nil}
195
+ end
196
+ fix.stub_data
197
+
198
+ expect { fix.check
199
+ }.to raise_error Mongo::Fixture::CollectionsNotEmptyError,
200
+ "The collection 'users' is not empty, all collections should be empty prior to testing"
201
+ end
202
+
203
+ it "should return true if all collections count equals 0" do
204
+ counter = stub :count => 0
205
+ database = stub
206
+ database.should_receive(:[]).with(:users).and_return counter
207
+ database.should_receive(:[]).with(:actions).and_return counter
208
+
209
+ Mongo::Fixture.any_instance.stub :push
210
+
211
+ fix = Mongo::Fixture.new nil, database
212
+ def fix.stub_data
213
+ @data = { :users => nil, :actions => nil }
214
+ end
215
+ fix.stub_data
216
+
217
+ fix.check.should === true
218
+ end
219
+
220
+ context "the check has been done and it passed before" do
221
+ it "should return true even if now collections don't pass" do
222
+ Mongo::Fixture.any_instance.stub :push
223
+
224
+ @counter = double 'counter'
225
+ @counter.stub :count do
226
+ @amount ||= 0
227
+ @amount += 1
228
+ 0 unless @amount > 5
229
+ end
230
+
231
+ @database = double 'database'
232
+ @database.stub(:[]).and_return @counter
233
+
234
+ @fix = Mongo::Fixture.new nil, @database
235
+ def @fix.stub_data
236
+ @data = { :users => nil, :tables => nil, :actions => nil, :schemas => nil }
237
+ end
238
+ @fix.stub_data
239
+ @fix.check.should === true
240
+ @fix.check.should === true # This looks confusing: let explain. The #count method as defined for the mock
241
+ # runs 4 times in the first check. In the second check, it runs 4 times again.
242
+ # After time 6 it returns a large amount, making the check fail.
243
+ # Of course, the fourth time is never reached since the second check is skipped
244
+ end
245
+ end
246
+
247
+ context "no fixture has been loaded" do
248
+ it "should fail with a missing fixture exception" do
249
+ fix = Mongo::Fixture.new
250
+ expect { fix.check
251
+ }.to raise_error Mongo::Fixture::MissingFixtureError,
252
+ "No fixture has been loaded, nothing to check"
253
+ end
254
+ end
255
+
256
+ context "a valid fixture has been loaded but no connection has been provided" do
257
+ before do
258
+ Fast.file.write "test/fixtures/test/users.yaml", "jane { name: Jane Doe }"
259
+ end
260
+ it "should fail with a missing database connection exception" do
261
+ fix = Mongo::Fixture.new :test
262
+ expect { fix.check
263
+ }.to raise_error Mongo::Fixture::MissingConnectionError,
264
+ "No connection has been provided, impossible to check"
265
+ end
266
+
267
+ after do
268
+ Fast.dir.remove! :test
269
+ end
270
+ end
271
+
272
+ context "a database is provided but no fixture" do
273
+ it "should fail with a missing fixture exception" do
274
+ database = double 'database'
275
+ fix = Mongo::Fixture.new nil, database
276
+ expect { fix.check
277
+ }.to raise_error Mongo::Fixture::MissingFixtureError,
278
+ "No fixture has been loaded, nothing to check"
279
+ end
280
+ end
281
+ end
282
+
283
+ describe "#connection" do
284
+ it "should return the Mongo connection passed as argument to the constructor" do
285
+ Mongo::Fixture.any_instance.stub :push
286
+ connection = stub
287
+ fix = Mongo::Fixture.new nil, connection
288
+ fix.connection.should === connection
289
+ end
290
+ end
291
+
292
+ describe "#connection=" do
293
+ it "sets the connection" do
294
+ fix = Mongo::Fixture.new
295
+ connection = stub
296
+ fix.connection = connection
297
+ fix.connection.should === connection
298
+ end
299
+
300
+ context "a check has been performed and I attempt to change the connection" do
301
+ before do
302
+ Fast.file.write "test/fixtures/test/users.yaml", "jane { name: Secret }"
303
+ end
304
+
305
+ it "should fail" do
306
+ database = double 'database'
307
+ database.stub(:[]).and_return mock(:count => 0)
308
+ Mongo::Fixture.any_instance.stub :push
309
+ fix = Mongo::Fixture.new :test, database
310
+ fix.check
311
+ expect { fix.connection = double 'database'
312
+ }.to raise_error Mongo::Fixture::ChangingConnectionIllegal,
313
+ "A check has already been performed, changing the connection now is illegal"
314
+ end
315
+
316
+ after do
317
+ Fast.dir.remove! :test
318
+ end
319
+ end
320
+ end
321
+
322
+ describe "#data" do
323
+ context "a fixture has been loaded" do
324
+ before do
325
+ Fast.file.write "test/fixtures/test/users.yaml", "jane { name: Jessica Dore }"
326
+ end
327
+
328
+ it "should return the fixture data" do
329
+ fix = Mongo::Fixture.new :test
330
+ fix.data.should have_key :users
331
+ fix.data[:users].should be_a SymbolMatrix
332
+ end
333
+
334
+ after do
335
+ Fast.dir.remove! :test
336
+ end
337
+ end
338
+
339
+ context "no fixture has been loaded" do
340
+ it "should return nil" do
341
+ fix = Mongo::Fixture.new
342
+ fix.data.should be_nil
343
+ end
344
+ end
345
+ end
346
+
347
+ describe "#push" do
348
+ it "should call #check" do
349
+ fix = Mongo::Fixture.new
350
+ def fix.stub_data
351
+ @data = {}
352
+ end
353
+ fix.stub_data
354
+ fix.should_receive :check
355
+ fix.push
356
+ end
357
+
358
+ context "a valid fixture and a database connection are provided" do
359
+ before do
360
+ Fast.file.write "test/fixtures/test/users.yaml", "john: { name: John, last_name: Wayne }"
361
+ Fast.file.write "test/fixtures/test/actions.yaml", "walk: { user_id: 1, action: Walks }"
362
+ @collection = stub
363
+ @database = stub :[] => @collection
364
+ @fix = Mongo::Fixture.new
365
+ @fix.load :test
366
+ @fix.connection = @database
367
+ end
368
+
369
+ it "should attempt to insert the data into the database" do
370
+ @collection.stub :count => 0
371
+ @collection.should_receive(:insert).with :name => "John", :last_name => "Wayne"
372
+ @collection.should_receive(:insert).with :user_id => 1, :action => "Walks"
373
+ @fix.push
374
+ end
375
+
376
+ after do
377
+ Fast.dir.remove! :test
378
+ end
379
+ end
380
+
381
+ context "a fixture with a field with a <raw> and a <processed> alternative" do
382
+ before do
383
+ Fast.file.write "test/fixtures/test/users.yaml", "user: { password: { raw: secret, processed: 35ferwt352 } }"
384
+ end
385
+
386
+ it "should insert the <processed> alternative" do
387
+ database = double 'database'
388
+ insertable = double 'collection'
389
+ insertable.stub :count => 0
390
+ insertable.should_receive(:insert).with :password => '35ferwt352'
391
+ database.stub(:[]).and_return insertable
392
+ fix = Mongo::Fixture.new :test, database, false
393
+ fix.push
394
+ end
395
+
396
+ after do
397
+ Fast.dir.remove! :test
398
+ end
399
+ end
400
+
401
+ context "a fixture with a field with alternatives yet missing the <processed> one" do
402
+ before do
403
+ Fast.file.write "test/fixtures/test/users.yaml", "hey: { pass: { raw: There } }"
404
+ end
405
+
406
+ it "should fail" do
407
+ database = double 'database', :[] => stub( 'collection', :count => 0, :drop => nil )
408
+ fix = Mongo::Fixture.new :test, database, false
409
+ expect { fix.push
410
+ }.to raise_error Mongo::Fixture::MissingProcessedValueError,
411
+ "In record 'hey' to be inserted into 'users', the processed value of field 'pass' is missing, aborting"
412
+ end
413
+
414
+
415
+ it "should call the rollback" do
416
+ database = double 'database', :[] => stub( 'collection', :count => 0, :drop => nil )
417
+ fix = Mongo::Fixture.new :test, database, false
418
+ fix.should_receive :rollback
419
+ expect { fix.push
420
+ }.to raise_error Mongo::Fixture::MissingProcessedValueError
421
+ end
422
+
423
+ after do
424
+ Fast.dir.remove! :test
425
+ end
426
+ end
427
+ end
428
+
429
+ # This should go in a dependency, pending refactoring TODO
430
+ describe "#simplify" do
431
+ context "when receiving a multidimensional hash containing a field with raw and processed" do
432
+ it "should convert it in a simple hash using the processed value as replacement" do
433
+ base_hash = {
434
+ :name => "Jane",
435
+ :band => "Witherspoons",
436
+ :pass => {
437
+ :raw => "secret",
438
+ :processed => "53oih7fhjdgj3f8="
439
+ },
440
+ :email => {
441
+ :raw => "Jane@gmail.com ",
442
+ :processed => "jane@gmail.com"
443
+ }
444
+ }
445
+
446
+ fix = Mongo::Fixture.new
447
+ simplified = fix.simplify base_hash
448
+ simplified.should == {
449
+ :name => "Jane",
450
+ :band => "Witherspoons",
451
+ :pass => "53oih7fhjdgj3f8=",
452
+ :email => "jane@gmail.com"
453
+ }
454
+ end
455
+ end
456
+
457
+ context "the multidimensional array is missing the processed part of the field" do
458
+ it "should raise an exception" do
459
+ base_hash = {
460
+ :name => "Jane",
461
+ :pass => {
462
+ :raw => "secret",
463
+ :not_processed => "53oih7fhjdgj3f8="
464
+ },
465
+ :email => {
466
+ :raw => "Jane@gmail.com ",
467
+ :processed => "jane@gmail.com"
468
+ }
469
+ }
470
+
471
+ fix = Mongo::Fixture.new
472
+ expect { fix.simplify base_hash
473
+ }.to raise_error Mongo::Fixture::MissingProcessedValueError,
474
+ "The processed value to insert into the db is missing from the field 'pass', aborting"
475
+ end
476
+ end
477
+ end
478
+
479
+ describe "#rollback" do
480
+ it "should check" do
481
+ fix = Mongo::Fixture.new
482
+ def fix.stub_data
483
+ @data = {}
484
+ end
485
+ fix.stub_data
486
+ fix.should_receive :check
487
+ fix.rollback
488
+ end
489
+
490
+ context "the check is failing" do
491
+ it "should raise a custom error for the rollback" do
492
+ fix = Mongo::Fixture.new
493
+ fix.stub(:check).and_raise Mongo::Fixture::CollectionsNotEmptyError
494
+ expect { fix.rollback
495
+ }.to raise_error Mongo::Fixture::RollbackIllegalError,
496
+ "The collections weren't empty to begin with, rollback aborted."
497
+ end
498
+ end
499
+
500
+ context "a check has been done and is passing" do
501
+ before do
502
+ @database = stub
503
+ @truncable = stub
504
+ @truncable.stub :count => 0
505
+ @database.stub(:[]).and_return @truncable
506
+
507
+ @fix = Mongo::Fixture.new
508
+ @fix.connection = @database
509
+ def @fix.stub_data
510
+ @data = { :users => nil, :actions => nil, :extras => nil }
511
+ end
512
+ @fix.stub_data
513
+
514
+ @fix.check.should === true
515
+ end
516
+
517
+ it "should call drop on each of the used collections" do
518
+ @truncable.should_receive(:drop).exactly(3).times
519
+ @fix.rollback
520
+ end
521
+ end
522
+ end
523
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongo-fixture
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Xavier Via
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongo
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: fast
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: symbolmatrix
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Flexible fixtures for the MongoDB Gem inspired in Rails 2 fixtures
79
+ email:
80
+ - xavier.via.canel@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - .pryrc
87
+ - .travis.yml
88
+ - Gemfile
89
+ - LICENSE
90
+ - README.md
91
+ - Rakefile
92
+ - features/configurable_fixtures_folder.feature
93
+ - features/play_around_with_fixtures.feature
94
+ - features/stepdefs/play_around_with_fixtures/background.rb
95
+ - features/stepdefs/play_around_with_fixtures/create_a_simple_fixture_push_it_and_rollback.rb
96
+ - features/stepdefs/play_around_with_fixtures/misconfigured_password_field.rb
97
+ - features/support/env.rb
98
+ - features/support/hooks.rb
99
+ - lib/mongo-fixture.rb
100
+ - lib/mongo-fixture/version.rb
101
+ - mongo-fixture.gemspec
102
+ - spec/mongo/fixture_spec.rb
103
+ homepage: http://github.com/Fetcher/mongo-fixture
104
+ licenses: []
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ segments:
116
+ - 0
117
+ hash: 94604481
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ segments:
125
+ - 0
126
+ hash: 94604481
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 1.8.24
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: Flexible fixtures for the MongoDB Gem inspired in Rails 2 fixtures
133
+ test_files:
134
+ - features/configurable_fixtures_folder.feature
135
+ - features/play_around_with_fixtures.feature
136
+ - features/stepdefs/play_around_with_fixtures/background.rb
137
+ - features/stepdefs/play_around_with_fixtures/create_a_simple_fixture_push_it_and_rollback.rb
138
+ - features/stepdefs/play_around_with_fixtures/misconfigured_password_field.rb
139
+ - features/support/env.rb
140
+ - features/support/hooks.rb
141
+ - spec/mongo/fixture_spec.rb