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