begin require "bundler/gem_tasks" rescue LoadError # bundler not installed end require 'rake/testtask' Rake::TestTask.new(:test) do |test| test.libs << 'lib' << 'test' test.pattern = 'test/**/*_test.rb' test.verbose = false end task :spec, :path, :action do |t, args| args.with_defaults(:path => '*/*', :action => 'ci') stats = [[0] * 5] not_found = [] mspec_cmds(args[:path], args[:action]) do |cmd, path| result = `#{cmd}` match = result.match(/(\d+) files?, (\d+) examples?, (\d+) expectations?, (\d+) failures?, (\d+) errors?/) if match.nil? puts "*** mspec returned with unexpected results:" puts result puts "Command was:", cmd fail "Unexpected output from mspec" end _, ex, p, f, e = data = match.captures.map{|x| x.to_i} not_found << path if ex == 0 stats << data if f + e > 0 puts cmd puts result else print "." STDOUT.flush end end $:.unshift 'lib' require 'backports/rails' _, ex, p, f, e = stats = stats.transpose.map{|x| x.sum} puts "*** Overall:", stats.zip(%w[files examples expectations failures errors]).map{|a| a.join(' ')}.join(', ') puts "No spec found for #{not_found.join(', ')}" unless not_found.empty? fail unless f + e == 0 end task :all_spec do # Necessary because of argument passing bug in 1.8.7 Rake::Task[:spec].invoke end task :spec_tag, :path do |t, args| Rake::Task[:spec].invoke(args[:path], 'tag -G fails') end task :default => [:test, :all_spec] DEPENDENCIES = Hash.new([]).merge!( '1.8.7/argf/chars' => 'backports/1.8.7/string/each_char', '1.8.7/argf/each_char' => 'backports/1.8.7/string/each_char', '1.8.7/array/cycle' => 'backports/1.8.7/stop_iteration', '1.8.7/enumerable/entries' => ['backports/1.8.7/enumerable/each_with_index', 'backports/1.8.7/enumerable/to_a'], '1.8.7/enumerator/rewind' => 'backports/1.8.7/enumerator/next', '1.8.7/hash/reject' => 'backports/1.8.7/integer/even', '1.9.1/hash/rassoc' => 'backports/1.9.1/hash/key', '1.9.1/proc/lambda' => 'backports/1.9.1/proc/curry', '1.9.2/complex/to_r' => 'complex', '1.9.2/array/select' => 'backports/1.8.7/array/select', '1.9.2/hash/select' => 'backports/1.8.7/hash/select', '1.9.2/enumerable/each_entry' => 'backports/1.8.7/enumerable/each_with_index', '2.0.0/hash/to_h' => 'backports/1.9.1/hash/default_proc' ) { :each_with_index => %w[enumerable/detect enumerable/find enumerable/find_all enumerable/select enumerable/to_a], :first => %w[enumerable/cycle io/bytes io/chars io/each_byte io/each_char io/lines io/each_line] }.each do |req, libs| libs.each{|l| DEPENDENCIES["1.8.7/#{l}"] = "backports/1.8.7/enumerable/#{req}" } end # These cause actual errors while loading in 1.8: IGNORE_IN_18 = %w[ 1.9.1/symbol/length 1.9.1/symbol/size 1.9.3/string/byteslice 1.8.7/proc/yield 1.9.1/proc/case_compare ] def mspec_cmds(pattern, action='ci') pattern = "lib/backports/*.*.*/#{pattern}.rb" Dir.glob(pattern) do |lib_path| _match, version, path = lib_path.match(/backports\/(\d\.\d\.\d)\/(.*)\.rb/).to_a next if path =~ /stdlib/ next if version <= RUBY_VERSION version_path = "#{version}/#{path}" next if IGNORE_IN_18.include? version_path if RUBY_VERSION < '1.9' deps = [*DEPENDENCIES[version_path]].map{|p| "-r #{p}"}.join(' ') klass, method = path.split('/') path = [klass.gsub('_', ''), method].join('/') # don't ask me why RubySpec uses matchdata instead of match_data yield %W[mspec #{action} -I lib -r ./set_version/#{version} #{deps} -r backports/#{version_path} -C spec rubyspec/core/#{path}_spec.rb ].join(' '), path end end