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.
Files changed (41) hide show
  1. data/.rspec +1 -0
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +50 -0
  4. data/README.md +51 -13
  5. data/Rakefile +7 -0
  6. data/doc/minidusen_test.png +0 -0
  7. data/gemfiles/Gemfile.2.3.mysql2 +11 -0
  8. data/gemfiles/Gemfile.2.3.mysql2.lock +29 -0
  9. data/gemfiles/Gemfile.3.2.mysql2 +11 -0
  10. data/gemfiles/Gemfile.3.2.mysql2.lock +54 -0
  11. data/gemfiles/Gemfile.4.2.mysql2 +9 -0
  12. data/gemfiles/Gemfile.4.2.mysql2.lock +58 -0
  13. data/gemfiles/Gemfile.4.2.pg +9 -0
  14. data/gemfiles/Gemfile.4.2.pg.lock +58 -0
  15. data/gemfiles/Gemfile.5.0.mysql2 +9 -0
  16. data/gemfiles/Gemfile.5.0.mysql2.lock +55 -0
  17. data/gemfiles/Gemfile.5.0.pg +9 -0
  18. data/gemfiles/Gemfile.5.0.pg.lock +55 -0
  19. data/lib/gemika/database.rb +11 -23
  20. data/lib/gemika/env.rb +115 -0
  21. data/lib/gemika/matrix.rb +97 -45
  22. data/lib/gemika/rspec.rb +37 -10
  23. data/lib/gemika/tasks/matrix.rb +24 -4
  24. data/lib/gemika/version.rb +1 -1
  25. data/lib/gemika.rb +2 -1
  26. data/spec/fixtures/travis_yml/Gemfile_without_gemika +1 -0
  27. data/spec/fixtures/travis_yml/excludes.yml +12 -0
  28. data/spec/fixtures/travis_yml/gemfile_without_gemika.yml +5 -0
  29. data/spec/fixtures/travis_yml/missing_gemfile.yml +5 -0
  30. data/spec/fixtures/travis_yml/two_by_two.yml +7 -0
  31. data/spec/gemika/database_spec.rb +15 -0
  32. data/spec/gemika/matrix_spec.rb +146 -0
  33. data/spec/spec_helper.rb +18 -0
  34. data/spec/support/database.rb +8 -0
  35. data/spec/support/database.sample.yml +10 -0
  36. data/spec/support/database.travis.yml +9 -0
  37. data/spec/support/database.yml +10 -0
  38. data/spec/support/models.rb +3 -0
  39. metadata +72 -21
  40. checksums.yaml +0 -7
  41. 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
- @rows.each { |row| validate_row(row) }
15
- @results = {}
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 |entry|
22
- gemfile = entry['gemfile']
23
- if compatible?(entry)
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
- ENV['BUNDLE_GEMFILE'] = gemfile
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[entry] = tint('Success', COLOR_SUCCESS)
90
+ @results[row] = tint('Success', COLOR_SUCCESS)
30
91
  else
31
- @results[entry] = tint('Failed', COLOR_FAILURE)
92
+ @results[row] = tint('Failed', COLOR_FAILURE)
32
93
  end
33
94
  else
34
- @results[entry] = tint("Skipped", COLOR_WARNING)
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
- travis_yml = YAML.load_file('.travis.yml')
42
- rubies = travis_yml.fetch('rvm')
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
- def validate_row(row)
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
- attr_reader :rows
69
-
70
- def compatible?(entry)
71
- entry['rvm'] == RUBY_VERSION
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 + message + COLOR_RESET
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 { |entry| entry['gemfile'].size }.max
88
- ruby_size = @results.keys.map { |entry| entry['rvm'].size }.max
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['gemfile'].ljust(gemfile_size)} Ruby #{entry['rvm'].ljust(ruby_size)} #{result}"
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 @all_passed
97
- puts tint("All gemfiles succeeded for Ruby #{RUBY_VERSION}.", COLOR_SUCCESS)
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
- puts tint('Some gemfiles failed.', COLOR_FAILURE)
151
+ message = 'Some gemfiles failed'
152
+ puts tint(message, COLOR_FAILURE)
101
153
  puts
102
- fail
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
- ::RSpec.configure do |config|
7
- config.around do |example|
8
- if example.metadata.fetch(:transaction, example.metadata.fetch(:rollback, true))
9
- ActiveRecord::Base.transaction do
10
- begin
11
- example.run
12
- ensure
13
- raise ActiveRecord::Rollback
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
 
@@ -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
- system("bundle exec rspec spec")
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
@@ -1,3 +1,3 @@
1
1
  module Gemika
2
- VERSION = '0.1.4'
2
+ VERSION = '0.2.0'
3
3
  end
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,12 @@
1
+ rvm:
2
+ - 2.1.8
3
+ - 2.3.1
4
+
5
+ gemfile:
6
+ - gemfiles/Gemfile1
7
+ - gemfiles/Gemfile2
8
+
9
+ matrix:
10
+ exclude:
11
+ - rvm: 2.1.8
12
+ gemfile: gemfiles/Gemfile1
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 2.1.8
3
+
4
+ gemfile:
5
+ - spec/fixtures/travis_yml/Gemfile_without_gemika
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 2.1.8
3
+
4
+ gemfile:
5
+ - gemfiles/nonexisting_gemfile
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 2.1.8
3
+ - 2.3.1
4
+
5
+ gemfile:
6
+ - gemfiles/Gemfile1
7
+ - gemfiles/Gemfile2
@@ -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
@@ -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
@@ -0,0 +1,8 @@
1
+ Gemika::Database.new.rewrite_schema! do
2
+
3
+ create_table :users do |t|
4
+ t.string :name
5
+ t.string :email
6
+ end
7
+
8
+ end
@@ -0,0 +1,10 @@
1
+ mysql:
2
+ database: gemika_test
3
+ host: localhost
4
+ username: root
5
+ password: secret
6
+
7
+ postgresql:
8
+ database: gemika_test
9
+ user:
10
+ password: