diff options
author | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-08 08:45:41 +0000 |
---|---|---|
committer | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-08 08:45:41 +0000 |
commit | 84e0bb34f395a7523d06202c4675649075fcb8f2 (patch) | |
tree | 0bbd28f684e745cb212761b7c74fe08668f85cc8 /spec/bundler/support/matchers.rb | |
parent | 398df4b4265b2f0406406ba064e3ecaae33b684c (diff) | |
download | ruby-84e0bb34f395a7523d06202c4675649075fcb8f2.tar.gz |
Merge bundler to standard libraries.
rubygems 2.7.x depends bundler-1.15.x. This is preparation for
rubygems and bundler migration.
* lib/bundler.rb, lib/bundler/*: files of bundler-1.15.4
* spec/bundler/*: rspec examples of bundler-1.15.4. I applied patches.
* https://github.com/bundler/bundler/pull/6007
* Exclude not working examples on ruby repository.
* Fake ruby interpriter instead of installed ruby.
* Makefile.in: Added test task named `test-bundler`. This task is only
working macOS/linux yet. I'm going to support Windows environment later.
* tool/sync_default_gems.rb: Added sync task for bundler.
[Feature #12733][ruby-core:77172]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59779 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/bundler/support/matchers.rb')
-rw-r--r-- | spec/bundler/support/matchers.rb | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/spec/bundler/support/matchers.rb b/spec/bundler/support/matchers.rb new file mode 100644 index 0000000000..9248360639 --- /dev/null +++ b/spec/bundler/support/matchers.rb @@ -0,0 +1,222 @@ +# frozen_string_literal: true +require "forwardable" +require "support/the_bundle" +module Spec + module Matchers + extend RSpec::Matchers + + class Precondition + include RSpec::Matchers::Composable + extend Forwardable + def_delegators :failing_matcher, + :failure_message, + :actual, + :description, + :diffable?, + :expected, + :failure_message_when_negated + + def initialize(matcher, preconditions) + @matcher = with_matchers_cloned(matcher) + @preconditions = with_matchers_cloned(preconditions) + @failure_index = nil + end + + def matches?(target, &blk) + return false if @failure_index = @preconditions.index {|pc| !pc.matches?(target, &blk) } + @matcher.matches?(target, &blk) + end + + def does_not_match?(target, &blk) + return false if @failure_index = @preconditions.index {|pc| !pc.matches?(target, &blk) } + if @matcher.respond_to?(:does_not_match?) + @matcher.does_not_match?(target, &blk) + else + !@matcher.matches?(target, &blk) + end + end + + def expects_call_stack_jump? + @matcher.expects_call_stack_jump? || @preconditions.any?(&:expects_call_stack_jump) + end + + def supports_block_expectations? + @matcher.supports_block_expectations? || @preconditions.any?(&:supports_block_expectations) + end + + def failing_matcher + @failure_index ? @preconditions[@failure_index] : @matcher + end + end + + def self.define_compound_matcher(matcher, preconditions, &declarations) + raise "Must have preconditions to define a compound matcher" if preconditions.empty? + define_method(matcher) do |*expected, &block_arg| + Precondition.new( + RSpec::Matchers::DSL::Matcher.new(matcher, declarations, self, *expected, &block_arg), + preconditions + ) + end + end + + MAJOR_DEPRECATION = /^\[DEPRECATED FOR 2\.0\]\s*/ + + RSpec::Matchers.define :lack_errors do + diffable + match do |actual| + actual.gsub(/#{MAJOR_DEPRECATION}.+[\n]?/, "") == "" + end + end + + RSpec::Matchers.define :eq_err do |expected| + diffable + match do |actual| + actual.gsub(/#{MAJOR_DEPRECATION}.+[\n]?/, "") == expected + end + end + + RSpec::Matchers.define :have_major_deprecation do |expected| + diffable + match do |actual| + actual.split(MAJOR_DEPRECATION).any? do |d| + !d.empty? && values_match?(expected, d.strip) + end + end + end + + RSpec::Matchers.define :have_dep do |*args| + dep = Bundler::Dependency.new(*args) + + match do |actual| + actual.length == 1 && actual.all? {|d| d == dep } + end + end + + RSpec::Matchers.define :have_gem do |*args| + match do |actual| + actual.length == args.length && actual.all? {|a| args.include?(a.full_name) } + end + end + + RSpec::Matchers.define :have_rubyopts do |*args| + args = args.flatten + args = args.first.split(/\s+/) if args.size == 1 + + match do |actual| + actual = actual.split(/\s+/) if actual.is_a?(String) + args.all? {|arg| actual.include?(arg) } && actual.uniq.size == actual.size + end + end + + define_compound_matcher :read_as, [exist] do |file_contents| + diffable + + match do |actual| + @actual = Bundler.read_file(actual) + values_match?(file_contents, @actual) + end + end + + def indent(string, padding = 4, indent_character = " ") + string.to_s.gsub(/^/, indent_character * padding).gsub("\t", " ") + end + + define_compound_matcher :include_gems, [be_an_instance_of(Spec::TheBundle)] do |*names| + match do + opts = names.last.is_a?(Hash) ? names.pop : {} + source = opts.delete(:source) + groups = Array(opts[:groups]) + groups << opts + @errors = names.map do |name| + name, version, platform = name.split(/\s+/) + version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name) + begin + run! "require '#{name}.rb'; puts #{version_const}", *groups + rescue => e + next "#{name} is not installed:\n#{indent(e)}" + end + out.gsub!(/#{MAJOR_DEPRECATION}.*$/, "") + actual_version, actual_platform = out.strip.split(/\s+/, 2) + unless Gem::Version.new(actual_version) == Gem::Version.new(version) + next "#{name} was expected to be at version #{version} but was #{actual_version}" + end + unless actual_platform == platform + next "#{name} was expected to be of platform #{platform} but was #{actual_platform}" + end + next unless source + begin + source_const = "#{Spec::Builders.constantize(name)}_SOURCE" + run! "require '#{name}/source'; puts #{source_const}", *groups + rescue + next "#{name} does not have a source defined:\n#{indent(e)}" + end + out.gsub!(/#{MAJOR_DEPRECATION}.*$/, "") + unless out.strip == source + next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{out}`" + end + end.compact + + @errors.empty? + end + + match_when_negated do + opts = names.last.is_a?(Hash) ? names.pop : {} + groups = Array(opts[:groups]) || [] + @errors = names.map do |name| + name, version = name.split(/\s+/, 2) + begin + run <<-R, *(groups + [opts]) + begin + require '#{name}' + puts #{Spec::Builders.constantize(name)} + rescue LoadError, NameError + puts "WIN" + end + R + rescue => e + next "checking for #{name} failed:\n#{e}" + end + next if out == "WIN" + next "expected #{name} to not be installed, but it was" if version.nil? + if Gem::Version.new(out) == Gem::Version.new(version) + next "expected #{name} (#{version}) not to be installed, but it was" + end + end.compact + + @errors.empty? + end + + failure_message do + super() + " but:\n" + @errors.map {|e| indent(e) }.join("\n") + end + + failure_message_when_negated do + super() + " but:\n" + @errors.map {|e| indent(e) }.join("\n") + end + end + RSpec::Matchers.define_negated_matcher :not_include_gems, :include_gems + RSpec::Matchers.alias_matcher :include_gem, :include_gems + + def have_lockfile(expected) + read_as(strip_whitespace(expected)) + end + + def plugin_should_be_installed(*names) + names.each do |name| + expect(Bundler::Plugin).to be_installed(name) + path = Pathname.new(Bundler::Plugin.installed?(name)) + expect(path + "plugins.rb").to exist + end + end + + def plugin_should_not_be_installed(*names) + names.each do |name| + expect(Bundler::Plugin).not_to be_installed(name) + end + end + + def lockfile_should_be(expected) + expect(bundled_app("Gemfile.lock")).to read_as(strip_whitespace(expected)) + end + end +end |