gemika 0.1.4 → 0.2.0
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/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +50 -0
- data/README.md +51 -13
- data/Rakefile +7 -0
- data/doc/minidusen_test.png +0 -0
- data/gemfiles/Gemfile.2.3.mysql2 +11 -0
- data/gemfiles/Gemfile.2.3.mysql2.lock +29 -0
- data/gemfiles/Gemfile.3.2.mysql2 +11 -0
- data/gemfiles/Gemfile.3.2.mysql2.lock +54 -0
- data/gemfiles/Gemfile.4.2.mysql2 +9 -0
- data/gemfiles/Gemfile.4.2.mysql2.lock +58 -0
- data/gemfiles/Gemfile.4.2.pg +9 -0
- data/gemfiles/Gemfile.4.2.pg.lock +58 -0
- data/gemfiles/Gemfile.5.0.mysql2 +9 -0
- data/gemfiles/Gemfile.5.0.mysql2.lock +55 -0
- data/gemfiles/Gemfile.5.0.pg +9 -0
- data/gemfiles/Gemfile.5.0.pg.lock +55 -0
- data/lib/gemika/database.rb +11 -23
- data/lib/gemika/env.rb +115 -0
- data/lib/gemika/matrix.rb +97 -45
- data/lib/gemika/rspec.rb +37 -10
- data/lib/gemika/tasks/matrix.rb +24 -4
- data/lib/gemika/version.rb +1 -1
- data/lib/gemika.rb +2 -1
- data/spec/fixtures/travis_yml/Gemfile_without_gemika +1 -0
- data/spec/fixtures/travis_yml/excludes.yml +12 -0
- data/spec/fixtures/travis_yml/gemfile_without_gemika.yml +5 -0
- data/spec/fixtures/travis_yml/missing_gemfile.yml +5 -0
- data/spec/fixtures/travis_yml/two_by_two.yml +7 -0
- data/spec/gemika/database_spec.rb +15 -0
- data/spec/gemika/matrix_spec.rb +146 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/database.rb +8 -0
- data/spec/support/database.sample.yml +10 -0
- data/spec/support/database.travis.yml +9 -0
- data/spec/support/database.yml +10 -0
- data/spec/support/models.rb +3 -0
- metadata +72 -21
- checksums.yaml +0 -7
- data/lib/gemika/doc/minidusen_test.png +0 -0
data/lib/gemika/env.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
module Gemika
|
2
|
+
module Env
|
3
|
+
|
4
|
+
class Error < StandardError; end
|
5
|
+
class Unknown < Error; end
|
6
|
+
|
7
|
+
def gemfile
|
8
|
+
ENV['BUNDLE_GEMFILE']
|
9
|
+
end
|
10
|
+
|
11
|
+
def gemfile=(path)
|
12
|
+
ENV['BUNDLE_GEMFILE'] = path
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_gemfile(path, *args, &block)
|
16
|
+
old_gemfile = gemfile
|
17
|
+
self.gemfile = path
|
18
|
+
block.call(*args)
|
19
|
+
ensure
|
20
|
+
self.gemfile = old_gemfile
|
21
|
+
end
|
22
|
+
|
23
|
+
def ruby_1_8?
|
24
|
+
RUBY_VERSION.start_with?('1.8.')
|
25
|
+
end
|
26
|
+
|
27
|
+
def pg?
|
28
|
+
gem?('pg')
|
29
|
+
end
|
30
|
+
|
31
|
+
def mysql2?
|
32
|
+
gem?('mysql2')
|
33
|
+
end
|
34
|
+
|
35
|
+
def active_record_2?
|
36
|
+
gem?('activerecord', '< 3')
|
37
|
+
end
|
38
|
+
|
39
|
+
def active_record_3_plus?
|
40
|
+
gem?('activerecord', '>= 3')
|
41
|
+
end
|
42
|
+
|
43
|
+
def rspec_1?
|
44
|
+
gem?('rspec', '< 2')
|
45
|
+
end
|
46
|
+
|
47
|
+
def rspec_2_plus?
|
48
|
+
gem?('rspec', '>= 2')
|
49
|
+
end
|
50
|
+
|
51
|
+
def rspec_binary
|
52
|
+
if rspec_1?
|
53
|
+
'spec'
|
54
|
+
elsif rspec_2_plus?
|
55
|
+
'rspec'
|
56
|
+
else
|
57
|
+
raise Unknown, 'Unknown rspec version'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def rspec_1_in_gemfile?(gemfile)
|
62
|
+
lockfile = "#{gemfile}.lock"
|
63
|
+
contents = File.read(lockfile)
|
64
|
+
contents =~ /\brspec \(1\./
|
65
|
+
end
|
66
|
+
|
67
|
+
def rspec_binary_for_gemfile(gemfile)
|
68
|
+
if rspec_1_in_gemfile?(gemfile)
|
69
|
+
'spec'
|
70
|
+
else
|
71
|
+
'rspec'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def gem?(name, requirement_string = nil)
|
76
|
+
gem = Gem.loaded_specs[name]
|
77
|
+
if gem
|
78
|
+
if requirement_string
|
79
|
+
requirement = Gem::Requirement.new(requirement_string)
|
80
|
+
version = gem.version
|
81
|
+
gem_requirement_satisfied_by_version?(requirement, version)
|
82
|
+
else
|
83
|
+
true
|
84
|
+
end
|
85
|
+
else
|
86
|
+
false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def travis?
|
91
|
+
!!ENV['TRAVIS']
|
92
|
+
end
|
93
|
+
|
94
|
+
def new_ordered_hash
|
95
|
+
if defined?(ActiveSupport::OrderedHash)
|
96
|
+
ActiveSupport::OrderedHash.new
|
97
|
+
else
|
98
|
+
{}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def gem_requirement_satisfied_by_version?(requirement, version)
|
105
|
+
if Env.ruby_1_8?
|
106
|
+
ops = Gem::Requirement::OPS
|
107
|
+
requirement.requirements.all? { |op, rv| (ops[op] || ops["="]).call version, rv }
|
108
|
+
else
|
109
|
+
requirement.satisfied_by?(version)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
extend self
|
114
|
+
end
|
115
|
+
end
|
data/lib/gemika/matrix.rb
CHANGED
@@ -1,8 +1,63 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'gemika/env'
|
2
3
|
|
3
4
|
module Gemika
|
4
5
|
class Matrix
|
5
6
|
|
7
|
+
class Error < StandardError; end
|
8
|
+
class Invalid < Error; end
|
9
|
+
class Failed < Error; end
|
10
|
+
class Incompatible < Error; end
|
11
|
+
|
12
|
+
class TravisConfig
|
13
|
+
class << self
|
14
|
+
|
15
|
+
def load_rows(options)
|
16
|
+
path = options.fetch(:path, '.travis.yml')
|
17
|
+
travis_yml = YAML.load_file(path)
|
18
|
+
rubies = travis_yml.fetch('rvm')
|
19
|
+
gemfiles = travis_yml.fetch('gemfile')
|
20
|
+
matrix_options = travis_yml.fetch('matrix', {})
|
21
|
+
excludes = matrix_options.fetch('exclude', [])
|
22
|
+
rows = []
|
23
|
+
rubies.each do |ruby|
|
24
|
+
gemfiles.each do |gemfile|
|
25
|
+
row = { 'rvm' => ruby, 'gemfile' => gemfile }
|
26
|
+
rows << row unless excludes.include?(row)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
rows = rows.map { |row| convert_row(row) }
|
30
|
+
rows
|
31
|
+
end
|
32
|
+
|
33
|
+
def convert_row(travis_row)
|
34
|
+
Row.new(:ruby => travis_row['rvm'], :gemfile => travis_row['gemfile'])
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Row
|
41
|
+
|
42
|
+
def initialize(attrs)
|
43
|
+
@ruby = attrs.fetch(:ruby)
|
44
|
+
@gemfile = attrs.fetch(:gemfile)
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_reader :ruby, :gemfile
|
48
|
+
|
49
|
+
def compatible_with_ruby?(current_ruby)
|
50
|
+
ruby == current_ruby
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate!
|
54
|
+
File.exists?(gemfile) or raise Invalid, "Gemfile not found: #{gemfile}"
|
55
|
+
contents = File.read(gemfile)
|
56
|
+
contents.include?('gemika') or raise Invalid, "Gemfile is missing gemika dependency: #{gemfile}"
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
6
61
|
COLOR_HEAD = "\e[44;97m"
|
7
62
|
COLOR_WARNING = "\e[33m"
|
8
63
|
COLOR_SUCCESS = "\e[32m"
|
@@ -11,68 +66,59 @@ module Gemika
|
|
11
66
|
|
12
67
|
def initialize(options)
|
13
68
|
@rows = options.fetch(:rows)
|
14
|
-
@
|
15
|
-
@
|
69
|
+
@silent = options.fetch(:silent, false)
|
70
|
+
@io = options.fetch(:io, STDOUT)
|
71
|
+
@color = options.fetch(:color, true)
|
72
|
+
validate = options.fetch(:validate, true)
|
73
|
+
@rows.each(&:validate!) if validate
|
74
|
+
@results = Env.new_ordered_hash
|
75
|
+
@compatible_count = 0
|
16
76
|
@all_passed = nil
|
77
|
+
@current_ruby = options.fetch(:current_ruby, RUBY_VERSION)
|
17
78
|
end
|
18
79
|
|
19
80
|
def each(&block)
|
20
81
|
@all_passed = true
|
21
|
-
rows.each do |
|
22
|
-
gemfile =
|
23
|
-
if
|
82
|
+
rows.each do |row|
|
83
|
+
gemfile = row.gemfile
|
84
|
+
if row.compatible_with_ruby?(current_ruby)
|
85
|
+
@compatible_count += 1
|
24
86
|
print_title gemfile
|
25
|
-
|
26
|
-
gemfile_passed = block.call
|
87
|
+
gemfile_passed = Env.with_gemfile(gemfile, row, &block)
|
27
88
|
@all_passed &= gemfile_passed
|
28
89
|
if gemfile_passed
|
29
|
-
@results[
|
90
|
+
@results[row] = tint('Success', COLOR_SUCCESS)
|
30
91
|
else
|
31
|
-
@results[
|
92
|
+
@results[row] = tint('Failed', COLOR_FAILURE)
|
32
93
|
end
|
33
94
|
else
|
34
|
-
@results[
|
95
|
+
@results[row] = tint("Skipped", COLOR_WARNING)
|
35
96
|
end
|
36
97
|
end
|
37
98
|
print_summary
|
38
99
|
end
|
39
100
|
|
40
|
-
def self.from_travis_yml
|
41
|
-
|
42
|
-
|
43
|
-
gemfiles = travis_yml.fetch('gemfile')
|
44
|
-
matrix_options = travis_yml.fetch('matrix', {})
|
45
|
-
excludes = matrix_options.fetch('exclude', [])
|
46
|
-
includes = matrix_options.fetch('include', [])
|
47
|
-
rows = []
|
48
|
-
rubies.each do |ruby|
|
49
|
-
gemfiles.each do |gemfile|
|
50
|
-
row = { 'rvm' => ruby, 'gemfile' => gemfile }
|
51
|
-
rows << row unless excludes.include?(row)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
rows += includes
|
55
|
-
new(:rows => rows)
|
101
|
+
def self.from_travis_yml(options = {})
|
102
|
+
rows = TravisConfig.load_rows(options)
|
103
|
+
new(options.merge(:rows => rows))
|
56
104
|
end
|
57
105
|
|
58
|
-
|
59
|
-
gemfile = row['gemfile']
|
60
|
-
File.exists?(gemfile) or raise ArgumentError, "Gemfile not found: #{gemfile}"
|
61
|
-
contents = File.read(gemfile)
|
62
|
-
contents.include?('gemika') or raise ArgumentError, "Gemfile is missing gemika dependency: #{gemfile}"
|
63
|
-
row
|
64
|
-
end
|
106
|
+
attr_reader :rows, :current_ruby
|
65
107
|
|
66
108
|
private
|
67
109
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
110
|
+
def puts(*args)
|
111
|
+
unless @silent
|
112
|
+
@io.puts(*args)
|
113
|
+
end
|
72
114
|
end
|
73
115
|
|
74
116
|
def tint(message, color)
|
75
|
-
color
|
117
|
+
if @color
|
118
|
+
color + message + COLOR_RESET
|
119
|
+
else
|
120
|
+
message
|
121
|
+
end
|
76
122
|
end
|
77
123
|
|
78
124
|
def print_title(title)
|
@@ -84,22 +130,28 @@ module Gemika
|
|
84
130
|
def print_summary
|
85
131
|
print_title 'Summary'
|
86
132
|
|
87
|
-
gemfile_size = @results.keys.map { |
|
88
|
-
ruby_size = @results.keys.map { |
|
133
|
+
gemfile_size = @results.keys.map { |row| row.gemfile.size }.max
|
134
|
+
ruby_size = @results.keys.map { |row| row.ruby.size }.max
|
89
135
|
|
90
136
|
@results.each do |entry, result|
|
91
|
-
puts "- #{entry
|
137
|
+
puts "- #{entry.gemfile.ljust(gemfile_size)} Ruby #{entry.ruby.ljust(ruby_size)} #{result}"
|
92
138
|
end
|
93
139
|
|
94
140
|
puts
|
95
141
|
|
96
|
-
if @
|
97
|
-
|
142
|
+
if @compatible_count == 0
|
143
|
+
message = "No gemfiles were compatible with Ruby #{RUBY_VERSION}"
|
144
|
+
puts tint(message, COLOR_FAILURE)
|
145
|
+
puts
|
146
|
+
raise Incompatible, message
|
147
|
+
elsif @all_passed
|
148
|
+
puts tint("All gemfiles succeeded for Ruby #{RUBY_VERSION}", COLOR_SUCCESS)
|
98
149
|
puts
|
99
150
|
else
|
100
|
-
|
151
|
+
message = 'Some gemfiles failed'
|
152
|
+
puts tint(message, COLOR_FAILURE)
|
101
153
|
puts
|
102
|
-
|
154
|
+
raise Failed, message
|
103
155
|
end
|
104
156
|
end
|
105
157
|
|
data/lib/gemika/rspec.rb
CHANGED
@@ -3,20 +3,47 @@ module Gemika
|
|
3
3
|
class << self
|
4
4
|
|
5
5
|
def configure_transactional_examples
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
if Env.rspec_1?
|
7
|
+
|
8
|
+
Spec::Runner.configure do |config|
|
9
|
+
|
10
|
+
config.before :each do
|
11
|
+
# from ActiveRecord::Fixtures#setup_fixtures
|
12
|
+
connection = ActiveRecord::Base.connection
|
13
|
+
connection.increment_open_transactions
|
14
|
+
connection.transaction_joinable = false
|
15
|
+
connection.begin_db_transaction
|
16
|
+
end
|
17
|
+
|
18
|
+
config.after :each do
|
19
|
+
# from ActiveRecord::Fixtures#teardown_fixtures
|
20
|
+
connection = ActiveRecord::Base.connection
|
21
|
+
if connection.open_transactions != 0
|
22
|
+
connection.rollback_db_transaction
|
23
|
+
connection.decrement_open_transactions
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
else
|
30
|
+
|
31
|
+
::RSpec.configure do |config|
|
32
|
+
config.around do |example|
|
33
|
+
if example.metadata.fetch(:transaction, example.metadata.fetch(:rollback, true))
|
34
|
+
ActiveRecord::Base.transaction do
|
35
|
+
begin
|
36
|
+
example.run
|
37
|
+
ensure
|
38
|
+
raise ActiveRecord::Rollback
|
39
|
+
end
|
14
40
|
end
|
41
|
+
else
|
42
|
+
example.run
|
15
43
|
end
|
16
|
-
else
|
17
|
-
example.run
|
18
44
|
end
|
19
45
|
end
|
46
|
+
|
20
47
|
end
|
21
48
|
end
|
22
49
|
|
data/lib/gemika/tasks/matrix.rb
CHANGED
@@ -1,26 +1,46 @@
|
|
1
1
|
require 'gemika/matrix'
|
2
2
|
|
3
|
+
module Gemika
|
4
|
+
module Tasks
|
5
|
+
RSPEC_ARGS = '--color spec'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
3
9
|
namespace :matrix do
|
4
10
|
|
5
11
|
desc "Run specs for all Ruby #{RUBY_VERSION} gemfiles"
|
6
12
|
task :spec do
|
7
|
-
Gemika::Matrix.from_travis_yml.each do
|
8
|
-
|
13
|
+
Gemika::Matrix.from_travis_yml.each do |row|
|
14
|
+
rspec_binary = Gemika::Env.rspec_binary_for_gemfile(row.gemfile)
|
15
|
+
args = Gemika::Tasks::RSPEC_ARGS
|
16
|
+
system("bundle exec #{rspec_binary} #{args}")
|
9
17
|
end
|
10
18
|
end
|
11
19
|
|
12
20
|
desc "Install all Ruby #{RUBY_VERSION} gemfiles"
|
13
21
|
task :install do
|
14
|
-
Gemika::Matrix.from_travis_yml.each do
|
22
|
+
Gemika::Matrix.from_travis_yml.each do |row|
|
15
23
|
system('bundle install')
|
16
24
|
end
|
17
25
|
end
|
18
26
|
|
19
27
|
desc "Update all Ruby #{RUBY_VERSION} gemfiles"
|
20
28
|
task :update, :gems do |t, args|
|
21
|
-
Gemika::Matrix.from_travis_yml.each do
|
29
|
+
Gemika::Matrix.from_travis_yml.each do |row|
|
22
30
|
system("bundle update #{args[:gems]}")
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
34
|
end
|
35
|
+
|
36
|
+
namespace :gemika do
|
37
|
+
|
38
|
+
# Private task to pick the correct RSpec binary
|
39
|
+
# (spec in RSpec 1, rspec in RSpec 2+)
|
40
|
+
task :spec do
|
41
|
+
rspec_binary = Gemika::Env.rspec_binary
|
42
|
+
args = Gemika::Tasks::RSPEC_ARGS
|
43
|
+
system("bundle exec #{rspec_binary} #{args}")
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/lib/gemika/version.rb
CHANGED
data/lib/gemika.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'gemika/version'
|
2
|
+
require 'gemika/env'
|
2
3
|
require 'gemika/database' if defined?(ActiveRecord)
|
3
4
|
require 'gemika/matrix'
|
4
|
-
require 'gemika/rspec' if defined?(RSpec)
|
5
|
+
require 'gemika/rspec' if defined?(RSpec) || defined?(Spec)
|
5
6
|
|
6
7
|
# don't load tasks by default
|
@@ -0,0 +1 @@
|
|
1
|
+
gem 'some-gem'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper' # can't move this to .rspec in RSpec 1
|
2
|
+
|
3
|
+
describe Gemika::Database do
|
4
|
+
|
5
|
+
it 'connects ActiveRecord to the database in database.yml, then migrates the schema' do
|
6
|
+
user = User.create!(:email => 'foo@bar.com')
|
7
|
+
database_user = User.first
|
8
|
+
user.email.should == database_user.email
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'wraps each example in a transaction that is rolled back when the transaction ends' do
|
12
|
+
User.count.should == 0
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'spec_helper' # can't move this to .rspec in RSpec 1
|
2
|
+
|
3
|
+
describe Gemika::Matrix do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@original_bundle_gemfile = ENV['BUNDLE_GEMFILE']
|
7
|
+
end
|
8
|
+
|
9
|
+
after :each do
|
10
|
+
# Make sure failing tests are not messing out our environment
|
11
|
+
ENV['BUNDLE_GEMFILE'] = @original_bundle_gemfile
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#each' do
|
15
|
+
|
16
|
+
it "calls the block with each matrix row, setting ENV['BUNDLE_GEMFILE'] to the respective gemfile" do
|
17
|
+
current_ruby = '2.1.8'
|
18
|
+
row1 = Gemika::Matrix::Row.new(:ruby => current_ruby, :gemfile => 'gemfiles/Gemfile1')
|
19
|
+
row2 = Gemika::Matrix::Row.new(:ruby => current_ruby, :gemfile => 'gemfiles/Gemfile2')
|
20
|
+
matrix = Gemika::Matrix.new(:rows =>[row1, row2], :validate => false, :current_ruby => current_ruby, :silent => true)
|
21
|
+
spy = double('block')
|
22
|
+
spy.should_receive(:observe_gemfile).with('gemfiles/Gemfile1')
|
23
|
+
spy.should_receive(:observe_gemfile).with('gemfiles/Gemfile2')
|
24
|
+
matrix.each do
|
25
|
+
spy.observe_gemfile(ENV['BUNDLE_GEMFILE'])
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'only calls the block with rows compatible with the current Ruby' do
|
31
|
+
current_ruby = '2.1.8'
|
32
|
+
other_ruby = '2.3.1'
|
33
|
+
row1 = Gemika::Matrix::Row.new(:ruby => current_ruby, :gemfile => 'gemfiles/Gemfile1')
|
34
|
+
row2 = Gemika::Matrix::Row.new(:ruby => other_ruby, :gemfile => 'gemfiles/Gemfile2')
|
35
|
+
matrix = Gemika::Matrix.new(:rows =>[row1, row2], :validate => false, :current_ruby => current_ruby, :silent => true)
|
36
|
+
spy = double('block')
|
37
|
+
spy.should_receive(:observe_gemfile).with('gemfiles/Gemfile1')
|
38
|
+
spy.should_not_receive(:observe_gemfile).with('gemfiles/Gemfile2')
|
39
|
+
matrix.each do
|
40
|
+
spy.observe_gemfile(ENV['BUNDLE_GEMFILE'])
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "resets ENV['BUNDLE GEMFILE'] to its initial value afterwards" do
|
46
|
+
original_env = ENV['BUNDLE_GEMFILE']
|
47
|
+
original_env.should be_present
|
48
|
+
current_ruby = '2.1.8'
|
49
|
+
row = Gemika::Matrix::Row.new(:ruby => current_ruby, :gemfile => 'gemfiles/Gemfile1')
|
50
|
+
matrix = Gemika::Matrix.new(:rows =>[row], :validate => false, :current_ruby => current_ruby, :silent => true)
|
51
|
+
matrix.each { true }
|
52
|
+
ENV['BUNDLE_GEMFILE'].should == original_env
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'prints an overview of which gemfiles have passed, which have failed, which were skipped' do
|
56
|
+
row1 = Gemika::Matrix::Row.new(:ruby => '2.1.8', :gemfile => 'gemfiles/GemfileAlpha')
|
57
|
+
row2 = Gemika::Matrix::Row.new(:ruby => '2.1.8', :gemfile => 'gemfiles/GemfileBeta')
|
58
|
+
row3 = Gemika::Matrix::Row.new(:ruby => '2.3.1', :gemfile => 'gemfiles/GemfileAlpha')
|
59
|
+
require 'stringio'
|
60
|
+
actual_output = ''
|
61
|
+
io = StringIO.new(actual_output)
|
62
|
+
matrix = Gemika::Matrix.new(:rows =>[row1, row2, row3], :validate => false, :current_ruby => '2.1.8', :io => io, :color => false)
|
63
|
+
commands = [
|
64
|
+
lambda { io.puts 'Successful output'; true },
|
65
|
+
lambda { io.puts 'Failed output'; false },
|
66
|
+
lambda { io.puts 'Skipped output'; false }
|
67
|
+
]
|
68
|
+
expect { matrix.each { commands.shift.call } }.to raise_error(Gemika::Matrix::Failed)
|
69
|
+
expected_output = <<EOF
|
70
|
+
gemfiles/GemfileAlpha
|
71
|
+
|
72
|
+
Successful output
|
73
|
+
|
74
|
+
gemfiles/GemfileBeta
|
75
|
+
|
76
|
+
Failed output
|
77
|
+
|
78
|
+
Summary
|
79
|
+
|
80
|
+
- gemfiles/GemfileAlpha Ruby 2.1.8 Success
|
81
|
+
- gemfiles/GemfileBeta Ruby 2.1.8 Failed
|
82
|
+
- gemfiles/GemfileAlpha Ruby 2.3.1 Skipped
|
83
|
+
|
84
|
+
Some gemfiles failed
|
85
|
+
EOF
|
86
|
+
actual_output.strip.should == expected_output.strip
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should raise an error if a row failed (returns false)' do
|
90
|
+
current_ruby = '2.1.8'
|
91
|
+
row = Gemika::Matrix::Row.new(:ruby => current_ruby, :gemfile => 'gemfiles/Gemfile')
|
92
|
+
matrix = Gemika::Matrix.new(:rows =>[row], :validate => false, :current_ruby => current_ruby, :silent => true)
|
93
|
+
expect { matrix.each { false } }.to raise_error(Gemika::Matrix::Failed, /Some gemfiles failed/i)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should raise an error if no row if compatible with the current Ruby' do
|
97
|
+
current_ruby = '2.1.8'
|
98
|
+
other_ruby = '2.3.1'
|
99
|
+
row = Gemika::Matrix::Row.new(:ruby => other_ruby, :gemfile => 'gemfiles/Gemfile')
|
100
|
+
matrix = Gemika::Matrix.new(:rows =>[row], :validate => false, :current_ruby => current_ruby, :silent => true)
|
101
|
+
expect { matrix.each { false } }.to raise_error(Gemika::Matrix::Incompatible, /No gemfiles were compatible/i)
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '.from_travis_yml' do
|
107
|
+
|
108
|
+
it 'builds a matrix by combining Ruby versions and gemfiles from a Travis CI configuration file' do
|
109
|
+
path = 'spec/fixtures/travis_yml/two_by_two.yml'
|
110
|
+
matrix = Gemika::Matrix.from_travis_yml(:path => path, :validate => false)
|
111
|
+
matrix.rows.size.should == 4
|
112
|
+
matrix.rows[0].ruby.should == '2.1.8'
|
113
|
+
matrix.rows[0].gemfile.should == 'gemfiles/Gemfile1'
|
114
|
+
matrix.rows[1].ruby.should == '2.1.8'
|
115
|
+
matrix.rows[1].gemfile.should == 'gemfiles/Gemfile2'
|
116
|
+
matrix.rows[2].ruby.should == '2.3.1'
|
117
|
+
matrix.rows[2].gemfile.should == 'gemfiles/Gemfile1'
|
118
|
+
matrix.rows[3].ruby.should == '2.3.1'
|
119
|
+
matrix.rows[3].gemfile.should == 'gemfiles/Gemfile2'
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'allows to exclude rows from the matrix' do
|
123
|
+
path = 'spec/fixtures/travis_yml/excludes.yml'
|
124
|
+
matrix = Gemika::Matrix.from_travis_yml(:path => path, :validate => false)
|
125
|
+
matrix.rows.size.should == 3
|
126
|
+
matrix.rows[0].ruby.should == '2.1.8'
|
127
|
+
matrix.rows[0].gemfile.should == 'gemfiles/Gemfile2'
|
128
|
+
matrix.rows[1].ruby.should == '2.3.1'
|
129
|
+
matrix.rows[1].gemfile.should == 'gemfiles/Gemfile1'
|
130
|
+
matrix.rows[2].ruby.should == '2.3.1'
|
131
|
+
matrix.rows[2].gemfile.should == 'gemfiles/Gemfile2'
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'raises an error if a Gemfile does not exist' do
|
135
|
+
path = 'spec/fixtures/travis_yml/missing_gemfile.yml'
|
136
|
+
expect { Gemika::Matrix.from_travis_yml(:path => path) }.to raise_error(Gemika::Matrix::Invalid, /gemfile not found/i)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'raises an error if a Gemfile does not depend on "gemika"' do
|
140
|
+
path = 'spec/fixtures/travis_yml/gemfile_without_gemika.yml'
|
141
|
+
expect { Gemika::Matrix.from_travis_yml(:path => path) }.to raise_error(Gemika::Matrix::Invalid, /missing gemika dependency/i)
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$: << File.join(File.dirname(__FILE__), "/../../lib" )
|
2
|
+
|
3
|
+
require 'active_record'
|
4
|
+
require 'gemika'
|
5
|
+
|
6
|
+
ActiveRecord::Base.default_timezone = :local
|
7
|
+
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/*.rb"].sort.each {|f| require f}
|
9
|
+
Dir["#{File.dirname(__FILE__)}/shared_examples/*.rb"].sort.each {|f| require f}
|
10
|
+
|
11
|
+
Gemika::RSpec.configure_transactional_examples
|
12
|
+
|
13
|
+
if Gemika::Env.rspec_2_plus?
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }
|
16
|
+
config.mock_with(:rspec) { |c| c.syntax = [:should, :expect] }
|
17
|
+
end
|
18
|
+
end
|