mongo-fixture 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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