sequel-fixture 0.0.1

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