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