summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/mspec/lib/mspec/helpers.rb1
-rw-r--r--spec/mspec/lib/mspec/helpers/warning.rb9
-rw-r--r--spec/mspec/lib/mspec/runner/formatters/unit.rb2
-rw-r--r--spec/mspec/spec/helpers/suppress_warning_spec.rb19
-rw-r--r--spec/mspec/spec/utils/script_spec.rb13
-rw-r--r--spec/mspec/tool/sync/.gitignore4
-rw-r--r--spec/mspec/tool/sync/sync-rubyspec.rb210
-rw-r--r--spec/mspec/tool/sync/sync.yml4
8 files changed, 255 insertions, 7 deletions
diff --git a/spec/mspec/lib/mspec/helpers.rb b/spec/mspec/lib/mspec/helpers.rb
index f2d1c9fb21..90f9fd3fd4 100644
--- a/spec/mspec/lib/mspec/helpers.rb
+++ b/spec/mspec/lib/mspec/helpers.rb
@@ -10,3 +10,4 @@ require 'mspec/helpers/numeric'
require 'mspec/helpers/ruby_exe'
require 'mspec/helpers/scratch'
require 'mspec/helpers/tmp'
+require 'mspec/helpers/warning'
diff --git a/spec/mspec/lib/mspec/helpers/warning.rb b/spec/mspec/lib/mspec/helpers/warning.rb
new file mode 100644
index 0000000000..44d0e35dc5
--- /dev/null
+++ b/spec/mspec/lib/mspec/helpers/warning.rb
@@ -0,0 +1,9 @@
+class Object
+ def suppress_warning
+ verbose = $VERBOSE
+ $VERBOSE = nil
+ yield
+ ensure
+ $VERBOSE = verbose
+ end
+end
diff --git a/spec/mspec/lib/mspec/runner/formatters/unit.rb b/spec/mspec/lib/mspec/runner/formatters/unit.rb
index 69b68dc0d5..cebc18a49b 100644
--- a/spec/mspec/lib/mspec/runner/formatters/unit.rb
+++ b/spec/mspec/lib/mspec/runner/formatters/unit.rb
@@ -8,7 +8,7 @@ class UnitdiffFormatter < DottedFormatter
@exceptions.each do |exc|
outcome = exc.failure? ? "FAILED" : "ERROR"
print "\n#{count += 1})\n#{exc.description} #{outcome}\n"
- print exc.message, ": \n"
+ print exc.message, ":\n"
print exc.backtrace, "\n"
end
print "\n#{@tally.format}\n"
diff --git a/spec/mspec/spec/helpers/suppress_warning_spec.rb b/spec/mspec/spec/helpers/suppress_warning_spec.rb
new file mode 100644
index 0000000000..d16361fa55
--- /dev/null
+++ b/spec/mspec/spec/helpers/suppress_warning_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+require 'mspec/guards'
+require 'mspec/helpers'
+
+describe Object, "#suppress_warning" do
+ it "hides warnings" do
+ suppress_warning do
+ warn "should not be shown"
+ end
+ end
+
+ it "yields the block" do
+ a = 0
+ suppress_warning do
+ a = 1
+ end
+ a.should == 1
+ end
+end
diff --git a/spec/mspec/spec/utils/script_spec.rb b/spec/mspec/spec/utils/script_spec.rb
index 62f6787acd..20b5d293b0 100644
--- a/spec/mspec/spec/utils/script_spec.rb
+++ b/spec/mspec/spec/utils/script_spec.rb
@@ -356,9 +356,9 @@ describe MSpecScript, "#entries" do
end
it "returns the pattern in an array if it is a file" do
- File.should_receive(:expand_path).with("file").and_return("file/expanded")
- File.should_receive(:file?).with("file/expanded").and_return(true)
- @script.entries("file").should == ["file/expanded"]
+ File.should_receive(:expand_path).with("file").and_return("file/expanded.rb")
+ File.should_receive(:file?).with("file/expanded.rb").and_return(true)
+ @script.entries("file").should == ["file/expanded.rb"]
end
it "returns Dir['pattern/**/*_spec.rb'] if pattern is a directory" do
@@ -381,9 +381,10 @@ describe MSpecScript, "#entries" do
end
it "returns the pattern in an array if it is a file" do
- File.should_receive(:expand_path).with(@name).and_return(@name)
- File.should_receive(:file?).with(@name).and_return(true)
- @script.entries("name").should == [@name]
+ name = "#{@name}.rb"
+ File.should_receive(:expand_path).with(name).and_return(name)
+ File.should_receive(:file?).with(name).and_return(true)
+ @script.entries("name.rb").should == [name]
end
it "returns Dir['pattern/**/*_spec.rb'] if pattern is a directory" do
diff --git a/spec/mspec/tool/sync/.gitignore b/spec/mspec/tool/sync/.gitignore
new file mode 100644
index 0000000000..e64f1e8542
--- /dev/null
+++ b/spec/mspec/tool/sync/.gitignore
@@ -0,0 +1,4 @@
+/jruby
+/rubinius
+/ruby
+/truffleruby
diff --git a/spec/mspec/tool/sync/sync-rubyspec.rb b/spec/mspec/tool/sync/sync-rubyspec.rb
new file mode 100644
index 0000000000..fe8c4edbb6
--- /dev/null
+++ b/spec/mspec/tool/sync/sync-rubyspec.rb
@@ -0,0 +1,210 @@
+IMPLS = {
+ truffleruby: {
+ git: "https://github.com/graalvm/truffleruby.git",
+ from_commit: "f10ab6988d",
+ },
+ jruby: {
+ git: "https://github.com/jruby/jruby.git",
+ from_commit: "f10ab6988d",
+ },
+ rbx: {
+ git: "https://github.com/rubinius/rubinius.git",
+ },
+ mri: {
+ git: "https://github.com/ruby/ruby.git",
+ master: "trunk",
+ prefix: "spec/rubyspec",
+ },
+}
+
+# Assuming the rubyspec repo is a sibling of the mspec repo
+RUBYSPEC_REPO = File.expand_path("../../../../rubyspec", __FILE__)
+raise RUBYSPEC_REPO unless Dir.exist?(RUBYSPEC_REPO)
+
+NOW = Time.now
+
+class RubyImplementation
+ attr_reader :name
+
+ def initialize(name, data)
+ @name = name.to_s
+ @data = data
+ end
+
+ def git_url
+ @data[:git]
+ end
+
+ def default_branch
+ @data[:master] || "master"
+ end
+
+ def repo_name
+ File.basename(git_url, ".git")
+ end
+
+ def repo_org
+ File.basename(File.dirname(git_url))
+ end
+
+ def from_commit
+ from = @data[:from_commit]
+ "#{from}..." if from
+ end
+
+ def prefix
+ @data[:prefix] || "spec/ruby"
+ end
+
+ def rebased_branch
+ "#{@name}-rebased"
+ end
+end
+
+def sh(*args)
+ puts args.join(' ')
+ system(*args)
+ raise unless $?.success?
+end
+
+def branch?(name)
+ branches = `git branch`.sub('*', '').lines.map(&:strip)
+ branches.include?(name)
+end
+
+def update_repo(impl)
+ unless File.directory? impl.repo_name
+ sh "git", "clone", impl.git_url
+ end
+
+ Dir.chdir(impl.repo_name) do
+ puts Dir.pwd
+
+ sh "git", "checkout", impl.default_branch
+ sh "git", "pull"
+ end
+end
+
+def filter_commits(impl)
+ Dir.chdir(impl.repo_name) do
+ date = NOW.strftime("%F")
+ branch = "specs-#{date}"
+
+ unless branch?(branch)
+ sh "git", "checkout", "-b", branch
+ sh "git", "filter-branch", "-f", "--subdirectory-filter", impl.prefix, *impl.from_commit
+ sh "git", "push", "-f", RUBYSPEC_REPO, "#{branch}:#{impl.name}"
+ end
+ end
+end
+
+def rebase_commits(impl)
+ Dir.chdir(RUBYSPEC_REPO) do
+ sh "git", "checkout", "master"
+ sh "git", "pull"
+
+ rebased = impl.rebased_branch
+ if branch?(rebased)
+ puts "#{rebased} already exists, assuming it correct"
+ sh "git", "checkout", rebased
+ else
+ sh "git", "checkout", impl.name
+
+ if ENV["LAST_MERGE"]
+ last_merge = `git log -n 1 --format='%H %ct' #{ENV["LAST_MERGE"]}`
+ else
+ last_merge = `git log --grep='Merge ruby/spec commit' -n 1 --format='%H %ct'`
+ end
+ last_merge, commit_timestamp = last_merge.chomp.split(' ')
+
+ raise "Could not find last merge" unless last_merge
+ puts "Last merge is #{last_merge}"
+
+ commit_date = Time.at(Integer(commit_timestamp))
+ days_since_last_merge = (NOW-commit_date) / 86400
+ if days_since_last_merge > 60
+ raise "#{days_since_last_merge} since last merge, probably wrong commit"
+ end
+
+ puts "Rebasing..."
+ sh "git", "branch", "-D", rebased if branch?(rebased)
+ sh "git", "checkout", "-b", rebased, impl.name
+ sh "git", "rebase", "--onto", "master", last_merge
+ end
+ end
+end
+
+def test_new_specs
+ require "yaml"
+ Dir.chdir(RUBYSPEC_REPO) do
+ versions = YAML.load_file(".travis.yml")
+ versions = versions["matrix"]["include"].map { |job| job["rvm"] }
+ versions.delete "ruby-head"
+ min_version, max_version = versions.minmax
+
+ run_rubyspec = -> version {
+ command = "chruby #{version} && ../mspec/bin/mspec -j"
+ sh ENV["SHELL"], "-c", command
+ }
+ run_rubyspec[min_version]
+ run_rubyspec[max_version]
+ run_rubyspec["trunk"]
+ end
+end
+
+def verify_commits(impl)
+ puts
+ Dir.chdir(RUBYSPEC_REPO) do
+ history = `git log master...`
+ history.lines.slice_before(/^commit \h{40}$/).each do |commit, *message|
+ commit = commit.chomp.split.last
+ message = message.join
+ if /\W(#\d+)/ === message
+ puts "Commit #{commit} contains an unqualified issue number: #{$1}"
+ puts "Replace it with #{impl.repo_org}/#{impl.repo_name}#{$1}"
+ sh "git", "rebase", "-i", "#{commit}^"
+ end
+ end
+
+ puts "Manually check commit messages:"
+ sh "git", "log", "master..."
+ end
+end
+
+def fast_forward_master(impl)
+ Dir.chdir(RUBYSPEC_REPO) do
+ sh "git", "checkout", "master"
+ sh "git", "merge", "--ff-only", "#{impl.name}-rebased"
+ end
+end
+
+def check_ci
+ puts
+ puts <<-EOS
+ Push to master, and check that the CI passes:
+ https://github.com/ruby/spec/commits/master
+ EOS
+end
+
+def main(impls)
+ impls.each_pair do |impl, data|
+ impl = RubyImplementation.new(impl, data)
+ update_repo(impl)
+ filter_commits(impl)
+ rebase_commits(impl)
+ test_new_specs
+ verify_commits(impl)
+ fast_forward_master(impl)
+ check_ci
+ end
+end
+
+if ARGV == ["all"]
+ impls = IMPLS
+else
+ args = ARGV.map { |arg| arg.to_sym }
+ raise ARGV.to_s unless (args - IMPLS.keys).empty?
+ impls = IMPLS.select { |impl| args.include?(impl) }
+end
+
+main(impls)
diff --git a/spec/mspec/tool/sync/sync.yml b/spec/mspec/tool/sync/sync.yml
new file mode 100644
index 0000000000..c0e1690bf4
--- /dev/null
+++ b/spec/mspec/tool/sync/sync.yml
@@ -0,0 +1,4 @@
+mri: 4e95b8c265d4d365477a05fe6701186415576303
+truffleruby: c8fb3e592bf354cd67893555c671955cc54c32ff
+jruby: d834e4279090998ba3ef087d81278734cab4c50a
+rbx: 7799d9fa48467cdbfceeed6765a63366d9dc8b0e