1
0
Fork 0
mirror of https://github.com/thoughtbot/shoulda-matchers.git synced 2022-11-09 12:01:38 -05:00

Add new RSpec acceptance tests to replace Cucumber

This commit is contained in:
Elliot Winkler 2014-10-26 18:52:55 -06:00
parent f922613386
commit 3fb4cdb3b7
26 changed files with 1229 additions and 1 deletions

View file

@ -15,6 +15,13 @@ RSpec::Core::RakeTask.new('spec:unit') do |t|
t.verbose = false t.verbose = false
end end
RSpec::Core::RakeTask.new('spec:acceptance') do |t|
t.ruby_opts = '-w -r ./spec/report_warnings'
t.pattern = "spec/acceptance/**/*_spec.rb"
t.rspec_opts = '--color --format progress'
t.verbose = false
end
Cucumber::Rake::Task.new do |t| Cucumber::Rake::Task.new do |t|
options = [] options = []

View file

@ -0,0 +1,20 @@
require 'acceptance_spec_helper'
describe 'shoulda-matchers integrates with an ActiveModel project' do
specify 'and loads without errors' do
create_active_model_project
add_shoulda_matchers_to_project
write_file 'load_dependencies.rb', <<-FILE
require 'active_model'
require 'shoulda-matchers'
puts ActiveModel::VERSION::STRING
puts "Loaded all dependencies without errors"
FILE
result = run_command('bundle exec ruby load_dependencies.rb')
expect(result).to have_output('Loaded all dependencies without errors')
end
end

View file

@ -0,0 +1,56 @@
require 'acceptance_spec_helper'
describe 'shoulda-matchers has independent matchers' do
context 'specifically delegate_method' do
specify 'and integrates with a Ruby application that uses Minitest' do
create_generic_bundler_project
add_minitest_to_project
write_file 'lib/post_office.rb', <<-FILE
class PostOffice
end
FILE
write_file 'lib/courier.rb', <<-FILE
require 'forwardable'
class Courier
extend Forwardable
def_delegators :post_office, :deliver
attr_reader :post_office
def initialize(post_office)
@post_office = post_office
end
end
FILE
write_minitest_test 'test/courier_test.rb' do |test_case_superclass|
<<-FILE
require "test_helper"
require "courier"
require "post_office"
class CourierTest < #{test_case_superclass}
subject { Courier.new(post_office) }
should delegate_method(:deliver).to(:post_office)
def post_office
PostOffice.new
end
end
FILE
end
result = run_n_unit_tests('test/courier_test.rb')
expect(result).to indicate_number_of_tests_was_run(1)
expect(result).to have_output(
'Courier should delegate #deliver to #post_office object'
)
end
end
end

View file

@ -0,0 +1,139 @@
require 'acceptance_spec_helper'
describe 'shoulda-matchers integrates with Rails' do
before do
create_rails_application
write_file 'db/migrate/1_create_users.rb', <<-FILE
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
end
end
end
FILE
run_rake_tasks!('db:migrate', 'db:test:prepare')
write_file 'app/models/user.rb', <<-FILE
class User < ActiveRecord::Base
validates_presence_of :name
end
FILE
write_file 'app/controllers/examples_controller.rb', <<-FILE
class ExamplesController < ApplicationController
def show
@example = 'hello'
render nothing: true
end
end
FILE
configure_routes_with_single_wildcard_route
end
specify 'in a project that uses Test::Unit' do
updating_bundle do
add_gems_for_n_unit
add_shoulda_matchers_to_project
end
run_tests_for_n_unit
end
specify 'in a project that uses RSpec' do
updating_bundle do
add_gems_for_rspec
add_shoulda_matchers_to_project
end
run_tests_for_rspec
end
specify 'in a project that uses Spring' do
unless bundle_includes?('spring')
skip "Spring isn't a dependency of this Appraisal"
end
updating_bundle do
add_spring_to_project
add_gems_for_rspec
add_shoulda_matchers_to_project(manually: true)
end
run_command_within_bundle!('spring stop')
run_tests_for_rspec
end
specify 'in a project that combines both RSpec and Test::Unit' do
updating_bundle do
add_gems_for_n_unit
add_gems_for_rspec
add_shoulda_matchers_to_project
end
run_tests_for_n_unit
run_tests_for_rspec
end
def add_gems_for_n_unit
add_gem 'shoulda-context'
end
def add_gems_for_rspec
add_rspec_rails_to_project!
end
def run_tests_for_n_unit
write_file 'test/unit/user_test.rb', <<-FILE
require 'test_helper'
class UserTest < ActiveSupport::TestCase
should validate_presence_of(:name)
end
FILE
write_file 'test/functional/examples_controller_test.rb', <<-FILE
require 'test_helper'
class ExamplesControllerTest < ActionController::TestCase
def setup
get :show
end
should respond_with(:success)
end
FILE
result = run_n_unit_test_suite
expect(result).to indicate_that_tests_were_run(unit: 1, functional: 1)
expect(result).to have_output('User should require name to be set')
expect(result).to have_output('should respond with 200')
end
def run_tests_for_rspec
add_spec 'spec/models/user_spec.rb', <<-FILE
describe User do
it { should validate_presence_of(:name) }
end
FILE
add_spec 'spec/controllers/examples_controller_spec.rb', <<-FILE
describe ExamplesController, "show" do
before { get :show }
it { should respond_with(:success) }
end
FILE
result = run_rspec_suite
expect(result).to have_output('2 examples, 0 failures')
expect(result).to have_output('should require name to be set')
expect(result).to have_output('should respond with 200')
end
end

View file

@ -0,0 +1,21 @@
require 'rspec/core'
Dir[ File.join(File.expand_path('../support/acceptance/**/*.rb', __FILE__)) ].sort.each do |file|
require file
end
RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = :expect
end
if config.respond_to?(:infer_spec_type_from_file_location!)
config.infer_spec_type_from_file_location!
end
AcceptanceTests::Helpers.configure_example_group(config)
config.include AcceptanceTests::Matchers
end
$VERBOSE = true

View file

@ -0,0 +1,33 @@
require_relative 'helpers/active_model_helpers'
require_relative 'helpers/base_helpers'
require_relative 'helpers/command_helpers'
require_relative 'helpers/gem_helpers'
require_relative 'helpers/rails_version_helpers'
require_relative 'helpers/rspec_helpers'
require_relative 'helpers/ruby_version_helpers'
require_relative 'helpers/step_helpers'
module AcceptanceTests
module Helpers
def self.configure_example_group(example_group)
example_group.include(self)
example_group.before do
fs.clean
end
# example_group.around do |example|
# Bundler.with_clean_env { example.run }
# end
end
include ActiveModelHelpers
include BaseHelpers
include CommandHelpers
include GemHelpers
include RailsVersionHelpers
include RspecHelpers
include RubyVersionHelpers
include StepHelpers
end
end

View file

@ -0,0 +1,7 @@
module AcceptanceTests
module ActiveModelHelpers
def active_model_version
Bundler.definition.specs['activemodel'][0].version
end
end
end

View file

@ -0,0 +1,13 @@
module AcceptanceTests
module ArrayHelpers
def to_sentence(array)
if array.size == 1
array[0]
elsif array.size == 2
array.join(' and ')
else
to_sentence(array[1..-2].join(', '), [array[-1]])
end
end
end
end

View file

@ -0,0 +1,14 @@
require_relative '../../tests/filesystem'
require_relative '../../tests/bundle'
module AcceptanceTests
module BaseHelpers
def fs
@_fs ||= Tests::Filesystem.new
end
def bundle
@_bundle ||= Tests::Bundle.new
end
end
end

View file

@ -0,0 +1,51 @@
require_relative 'base_helpers'
require_relative '../../tests/command_runner'
module AcceptanceTests
module CommandHelpers
include BaseHelpers
extend RSpec::Matchers::DSL
def run_command(*args)
Tests::CommandRunner.run(*args) do |runner|
runner.directory = fs.project_directory
yield runner if block_given?
end
end
def run_command!(*args)
run_command(*args) do |runner|
runner.run_successfully = true
yield runner if block_given?
end
end
def run_command_within_bundle(*args)
run_command(*args) do |runner|
runner.command_prefix = 'bundle exec'
runner.env['BUNDLE_GEMFILE'] = fs.find_in_project('Gemfile').to_s
runner.around_command do |run_command|
Bundler.with_clean_env(&run_command)
end
yield runner if block_given?
end
end
def run_command_within_bundle!(*args)
run_command_within_bundle(*args) do |runner|
runner.run_successfully = true
yield runner if block_given?
end
end
def run_rake_tasks(*tasks)
run_command_within_bundle('rake', *tasks)
end
def run_rake_tasks!(*tasks)
run_command_within_bundle!('rake', *tasks)
end
end
end

View file

@ -0,0 +1,23 @@
require_relative 'base_helpers'
module AcceptanceTests
module FileHelpers
include BaseHelpers
def append_to_file(path, content, options = {})
fs.append_to_file(path, content, options)
end
def append_to_file_following(path, content_to_add, insertion_point)
fs.append_to_file_following(path, content_to_add, insertion_point)
end
def remove_from_file(path, pattern)
fs.remove_from_file(path, pattern)
end
def write_file(path, content)
fs.write(path, content)
end
end
end

View file

@ -0,0 +1,31 @@
require_relative 'base_helpers'
require_relative 'command_helpers'
require_relative 'file_helpers'
module AcceptanceTests
module GemHelpers
include BaseHelpers
include CommandHelpers
include FileHelpers
def add_gem(gem, *args)
bundle.add_gem(gem, *args)
end
def install_gems
bundle.install_gems
end
def updating_bundle(&block)
bundle.updating(&block)
end
def bundle_version_of(gem)
bundle.version_of(gem)
end
def bundle_includes?(gem)
bundle.includes?(gem)
end
end
end

View file

@ -0,0 +1,21 @@
module AcceptanceTests
module MinitestHelpers
def minitest_test_case_superclass
if minitest_gte_5?
'Minitest::Test'
else
'MiniTest::Unit::TestCase'
end
end
def minitest_gte_5?
if minitest_version
Gem::Requirement.new('>= 5').satisfied_by?(minitest_version)
end
end
def minitest_version
Bundler.definition.specs['minitest'][0].version
end
end
end

View file

@ -0,0 +1,13 @@
module AcceptanceTests
module PluralizationHelpers
def pluralize(count, singular_version, plural_version = nil)
plural_version ||= singular_version + 's'
if count == 1
"#{count} #{singular_version}"
else
"#{count} #{plural_version}"
end
end
end
end

View file

@ -0,0 +1,9 @@
module AcceptanceTests
module RailsVersionHelpers
include GemHelpers
def rails_version
bundle_version_of('rails')
end
end
end

View file

@ -0,0 +1,26 @@
module AcceptanceTests
module RspecHelpers
include GemHelpers
def rspec_rails_version
bundle_version_of('rspec-rails')
end
def add_spec(path, content)
content = "require '#{spec_helper_require_path}'\n#{content}"
write_file path, content
end
def spec_helper_require_path
if rspec_rails_version >= 3
'rails_helper'
else
'spec_helper'
end
end
def spec_helper_file_path
"spec/#{spec_helper_require_path}.rb"
end
end
end

View file

@ -0,0 +1,9 @@
require_relative '../../tests/version'
module AcceptanceTests
module RubyVersionHelpers
def ruby_version
Tests::Version.new(RUBY_VERSION)
end
end
end

View file

@ -0,0 +1,110 @@
require_relative 'file_helpers'
require_relative 'gem_helpers'
require_relative 'minitest_helpers'
module AcceptanceTests
module StepHelpers
include FileHelpers
include GemHelpers
include MinitestHelpers
extend RSpec::Matchers::DSL
def create_active_model_project
create_generic_bundler_project
add_gem 'activemodel', active_model_version
end
def create_generic_bundler_project
fs.create
run_command! 'bundle init'
end
def add_shoulda_matchers_to_project(options = {})
gem_options = { path: fs.root_directory }
if options[:manually]
gem_options[:require] = false
end
add_gem 'shoulda-matchers', gem_options
if options[:manually]
append_to_file spec_helper_file_path,
"require 'shoulda/matchers'",
following: "require 'rspec/rails'"
end
end
def add_minitest_to_project
add_gem 'shoulda-context'
add_gem 'minitest-reporters'
write_file 'test/test_helper.rb', <<-FILE
require 'minitest/autorun'
require 'minitest/reporters'
require 'shoulda/context'
require 'shoulda/matchers'
Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new)
FILE
end
def write_minitest_test(path, &block)
contents = block.call(minitest_test_case_superclass)
write_file(path, contents)
end
def run_n_unit_tests(*paths)
run_command 'ruby -I lib -I test', *paths
end
def run_n_unit_test_suite
run_rake_tasks('test', env: { TESTOPTS: '-v' })
end
def create_rails_application
command = "bundle exec rails new #{fs.project_directory} --skip-bundle"
run_command!(command) do |runner|
runner.directory = nil
end
updating_bundle do |bundle|
bundle.remove_gem 'turn'
bundle.remove_gem 'coffee-rails'
bundle.remove_gem 'uglifier'
# if ruby_version >= '1.9.3'
# bundle.add_gem 'rake', '~> 0.9'
# run_command! 'bundle update rake --local'
# end
end
end
def configure_routes_with_single_wildcard_route
write_file 'config/routes.rb', <<-FILE
Rails.application.routes.draw do
get ':controller(/:action(/:id(.:format)))'
end
FILE
end
def add_rspec_rails_to_project!
add_gem 'rspec-rails', rspec_rails_version
run_command_within_bundle!('rails g rspec:install')
remove_from_file '.rspec', '--warnings'
end
def run_rspec_suite
run_rake_tasks('spec', env: { SPEC_OPTS: '-fd' })
end
def add_spring_to_project
if rails_version < 4
add_gem 'spring'
end
add_gem 'spring-commands-rspec'
end
end
end

View file

@ -0,0 +1,31 @@
module AcceptanceTests
module Matchers
def have_output(output)
HaveOutputMatcher.new(output)
end
class HaveOutputMatcher
def initialize(output)
@output = output
end
def matches?(runner)
@runner = runner
runner.has_output?(output)
end
def failure_message
"Expected command to have output, but did not.\n\n" +
"Command: #{runner.formatted_command}\n\n" +
"Expected output:\n" +
output + "\n\n" +
"Actual output:\n" +
runner.elided_output
end
protected
attr_reader :output, :runner
end
end
end

View file

@ -0,0 +1,55 @@
require_relative '../helpers/pluralization_helpers'
require_relative '../helpers/rails_version_helpers'
module AcceptanceTests
module Matchers
def indicate_number_of_tests_was_run(expected_output)
IndicateNumberOfTestsWasRunMatcher.new(expected_output)
end
class IndicateNumberOfTestsWasRunMatcher
include PluralizationHelpers
include RailsVersionHelpers
def initialize(number)
@number = number
end
def matches?(runner)
@runner = runner
expected_output === actual_output
end
def failure_message
message = "Expected output to indicate that #{some_tests_were_run}.\n" +
"Expected output: #{expected_output}\n"
if actual_output.empty?
message << 'Actual output: (empty)'
else
message << "Actual output:\n#{actual_output}"
end
message
end
protected
attr_reader :number, :runner
private
def expected_output
/#{number} (tests|runs), #{number} assertions, 0 failures, 0 errors(, 0 skips)?/
end
def actual_output
runner.output
end
def some_tests_were_run
pluralize(number, 'test was', 'tests were') + ' run'
end
end
end
end

View file

@ -0,0 +1,103 @@
require_relative '../helpers/array_helpers'
require_relative '../helpers/pluralization_helpers'
require_relative '../helpers/rails_version_helpers'
module AcceptanceTests
module Matchers
def indicate_that_tests_were_run(series)
IndicateThatTestsWereRunMatcher.new(series)
end
class IndicateThatTestsWereRunMatcher
include ArrayHelpers
include PluralizationHelpers
include RailsVersionHelpers
def initialize(args)
@args = args
@series = args.values
end
def matches?(runner)
@runner = runner
!matching_expected_output.nil?
end
def failure_message
"Expected output to indicate that #{some_tests_were_run}.\n" +
"#{formatted_expected_output}\n" +
"#{formatted_actual_output}\n"
end
protected
attr_reader :args, :series, :runner
private
def expected_outputs
[
expected_output_for_rails_3,
expected_output_for_turn,
expected_output_for_rails_4
]
end
def matching_expected_output
@_matching_expected_output ||=
expected_outputs.detect do |expected_output|
actual_output =~ expected_output
end
end
def expected_output_for_rails_3
full_report = series.map do |number|
"#{number} tests, #{number} assertions, 0 failures, 0 errors(, 0 skips)?"
end.join('.+')
Regexp.new(full_report, Regexp::MULTILINE)
end
def expected_output_for_turn
full_report = series.map do |number|
"pass: #{number}, fail: 0, error: 0"
end.join('.+')
Regexp.new(full_report, Regexp::MULTILINE)
end
def expected_output_for_rails_4
total = series.inject(:+)
/#{total} (tests|runs), #{total} assertions, 0 failures, 0 errors(, 0 skips)?/
end
def formatted_expected_output
if matching_expected_output
"Expected output:\n#{matching_actual_output}"
else
"Expected output: (n/a)"
end
end
def actual_output
runner.output
end
def formatted_actual_output
if actual_output.empty?
"Actual output: (empty)"
else
"Actual output:\n#{actual_output}"
end
end
def some_tests_were_run
clauses = args.map do |type, number|
pluralize(number, "#{type} test was run", "#{type} tests were run")
end
to_sentence(clauses)
end
end
end
end

View file

@ -0,0 +1,94 @@
require_relative 'filesystem'
require_relative 'command_runner'
require_relative 'version'
module Tests
class Bundle
def initialize
@already_updating = false
@fs = Filesystem.new
end
def updating(&block)
if already_updating?
yield self
return
end
@already_updating = true
yield self
@already_updating = false
install_gems
end
def add_gem(gem, *args)
updating do
options = args.last.is_a?(Hash) ? args.pop : {}
version = args.shift
line = assemble_gem_line(gem, version, options)
fs.append_to_file('Gemfile', line)
end
end
def remove_gem(gem)
updating do
fs.remove_from_file('Gemfile', /^gem ("|')gem\1/)
end
end
def install_gems
CommandRunner.run!('bundle install --local') do |runner|
runner.retries = 5
end
end
def version_of(gem)
Version.new(Bundler.definition.specs[gem][0].version)
end
def includes?(gem)
Bundler.definition.dependencies.any? do |dependency|
dependency.name == gem
end
end
protected
attr_reader :fs
private
def already_updating?
@already_updating
end
def assemble_gem_line(gem, version, options)
formatted_options = options.
map { |key, value| "#{key}: #{formatted_value(value)}" }.
join(', ')
line = %(gem '#{gem}')
if version
line << %(, '#{version}')
end
if options.any?
line << %(, #{formatted_options})
end
line << "\n"
end
def formatted_value(value)
if value.is_a?(Pathname)
value.to_s.inspect
else
value.inspect
end
end
end
end

View file

@ -0,0 +1,213 @@
require 'timeout'
require 'shellwords'
module Tests
class CommandRunner
TimeoutError = Class.new(StandardError)
def self.run(*args)
new(*args).tap do |runner|
yield runner
runner.call
end
end
def self.run!(*args)
run(*args) do |runner|
runner.run_successfully = true
yield runner if block_given?
end
end
attr_reader :status, :options, :env, :directory
attr_accessor :command_prefix, :run_quickly, :run_successfully, :retries,
:timeout
def initialize(*args)
@reader, @writer = IO.pipe
options = (args.last.is_a?(Hash) ? args.pop : {})
@args = args
@options = options.merge(
err: [:child, :out],
out: writer
)
@env = extract_env_from(@options)
@wrapper = ->(block) { block.call }
@command_prefix = ''
@directory = Dir.pwd
@run_quickly = false
@run_successfully = false
@retries = 1
@num_times_run = 0
@timeout = 20
end
def around_command(&block)
@wrapper = block
end
def directory=(directory)
@directory = directory || Dir.pwd
end
def formatted_command
[formatted_env, Shellwords.join(command)].
select { |value| !value.empty? }.
join(' ')
end
def call
possibly_retrying do
possibly_running_quickly do
debug { "\n\e[32mRunning command:\e[0m #{formatted_command}" }
wrapper.call(-> { run })
debug { "\n" + divider('START') + output + divider('END') }
if run_successfully && !success?
fail!
end
end
end
self
end
def stop
unless writer.closed?
writer.close
end
end
def output
@_output ||= begin
stop
without_colors(reader.read)
end
end
def elided_output
lines = output.split(/\n/)
new_lines = lines[0..4]
if lines.size > 10
new_lines << "(...#{lines.size - 10} more lines...)"
end
new_lines << lines[-5..-1]
new_lines.join("\n")
end
def success?
status.success?
end
def exit_status
status.exitstatus
end
def fail!
raise <<-MESSAGE
Command #{command.inspect} exited with status #{exit_status}.
Output:
#{divider('START') + output + divider('END')}
MESSAGE
end
def has_output?(expected_output)
output.include?(expected_output)
end
protected
attr_reader :args, :reader, :writer, :wrapper
private
def extract_env_from(options)
options.delete(:env) { {} }.inject({}) do |hash, (key, value)|
hash[key.to_s] = value
hash
end
end
def command
([command_prefix] + args).flatten.flat_map do |word|
Shellwords.split(word)
end
end
def formatted_env
env.map { |key, value| "#{key}=#{value.inspect}" }.join(' ')
end
def run
Dir.chdir(directory) do
system(env, *command, options)
end
@status = $?
end
def possibly_running_quickly(&block)
if run_quickly
begin
Timeout.timeout(timeout, &block)
rescue Timeout::Error
stop
message =
"Command timed out after #{timeout} seconds: #{formatted_command}\n" +
"Output:\n" +
elided_output
raise TimeoutError, message
end
else
yield
end
end
def possibly_retrying
begin
@num_times_run += 1
yield
rescue => error
debug { "#{error.class}: #{error.message}" }
if @num_times_run < @retries
sleep @num_times_run
retry
else
raise error
end
end
end
def divider(title = '')
total_length = 72
start_length = 3
string = ''
string << ('-' * start_length)
string << title
string << '-' * (total_length - start_length - title.length)
string << "\n"
string
end
def without_colors(string)
string.gsub(/\e\[\d+(?:;\d+)?m(.+?)\e\[0m/, '\1')
end
def debugging_enabled?
ENV['DEBUG_COMMANDS'] == '1'
end
def debug(&block)
if debugging_enabled?
puts block.call
end
end
end
end

View file

@ -0,0 +1,84 @@
require 'fileutils'
module Tests
class Filesystem
PROJECT_NAME = 'test-project'
ROOT_DIRECTORY = Pathname.new('../../../..').expand_path(__FILE__)
TEMP_DIRECTORY = ROOT_DIRECTORY.join('tmp/acceptance')
PROJECT_DIRECTORY = TEMP_DIRECTORY.join(PROJECT_NAME)
def root_directory
ROOT_DIRECTORY
end
def temp_directory
TEMP_DIRECTORY
end
def project_directory
PROJECT_DIRECTORY
end
def within_project(&block)
Dir.chdir(project_directory, &block)
end
def clean
if temp_directory.exist?
temp_directory.rmtree
end
end
def create
project_directory.mkpath
end
def find_in_project(path)
project_directory.join(path)
end
def open(path, *args, &block)
find_in_project(path).open(*args, &block)
end
def read(path)
find_in_project(path).read
end
def write(path, content)
pathname = find_in_project(path)
pathname.dirname.mkpath
pathname.open('w') { |f| f.write(content) }
end
def append_to_file(path, content, options = {})
if options[:following]
append_to_file_following(path, content, options[:following])
else
open(path, 'a') { |f| f.puts(content + "\n") }
end
end
def append_to_file_following(path, content_to_add, insertion_point)
content_to_add = content_to_add + "\n"
file_content = read(path)
file_lines = file_content.split("\n")
insertion_index = file_lines.find_index(insertion_point)
if insertion_index.nil?
raise "Cannot find #{insertion_point.inspect} in #{path}"
end
file_lines.insert(insertion_index + 1, content_to_add)
new_file_content = file_lines.join("\n")
write(path, new_file_content)
end
def remove_from_file(path, pattern)
content = read(path)
content.sub!(/#{pattern}\n/, '')
write(path, content)
end
end
end

View file

@ -0,0 +1,45 @@
module Tests
class Version
def initialize(version)
@version = Gem::Version.new(version.to_s + '')
end
def <(other_version)
compare?(:<, other_version)
end
def <=(other_version)
compare?(:<=, other_version)
end
def ==(other_version)
compare?(:==, other_version)
end
def >=(other_version)
compare?(:>=, other_version)
end
def >(other_version)
compare?(:>, other_version)
end
def =~(other_version)
Gem::Requirement.new(other_version).satisfied_by?(version)
end
def to_s
version.to_s
end
protected
attr_reader :version
private
def compare?(op, other_version)
Gem::Requirement.new("#{op} #{other_version}").satisfied_by?(version)
end
end
end

View file

@ -29,7 +29,7 @@ require 'rspec/rails'
PROJECT_ROOT = File.expand_path('../..', __FILE__) PROJECT_ROOT = File.expand_path('../..', __FILE__)
$LOAD_PATH << File.join(PROJECT_ROOT, 'lib') $LOAD_PATH << File.join(PROJECT_ROOT, 'lib')
Dir[ File.join(File.expand_path('../support/unit/**/*.rb', __FILE__)) ].each do |file| Dir[ File.join(File.expand_path('../support/unit/**/*.rb', __FILE__)) ].sort.each do |file|
require file require file
end end