File: _backport_guards_test.rb

package info (click to toggle)
ruby-backports 3.25.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,912 kB
  • sloc: ruby: 11,759; makefile: 6
file content (165 lines) | stat: -rw-r--r-- 5,666 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# This file tests that (old) standard library backports requiring doesn't break anything.
# It isn't relevant to Rubies > 2.0, since we stopped to backport stdlib.

if RUBY_VERSION < '2.0'
  require 'stringio'
  if RUBY_VERSION < '1.9'
    require 'enumerator'
    require 'generator' # Must require first, because of warning in Ruby 1.8.7 with `ruby -w -r generator -e ""`
  end
  require './test/test_helper'
  $bogus = []

  module Kernel
    def require_with_bogus_extension(lib)
      $bogus << lib
      require_without_bogus_extension(lib)
    end
    alias_method :require_without_bogus_extension, :require
    alias_method :require, :require_with_bogus_extension

    if defined? BasicObject and BasicObject.superclass
      BasicObject.send :undef_method, :require
      BasicObject.send :undef_method, :require_with_bogus_extension
    end
  end

  class AAA_TestBackportGuards < Test::Unit::TestCase
    def setup
      $VERBOSE = true
      @prev, $stderr = $stderr, StringIO.new
    end

    def teardown
      assert_equal '', $stderr.string
      $stderr = @prev
    end

    EXCLUDE = %w[require require_with_backports require_without_backports] # Overriden in all circumstances to load the std-lib
    EXCLUDE.map!(&:to_sym) if instance_methods.first.is_a?(Symbol)

    # For some very strange reason, Hash[kvp.flatten] doesn't always work in 1.8.6??
    def to_hash(key_value_pairs)
      h = {}
      key_value_pairs.each{|k,v| h[k] = v}
      h
    end

    # This returns all user defined methods on klass.
    # For Ruby 1.8.7 or below, it returns all methods, so we can at least check we are not adding new methods needlessly
    def class_signature(klass)
      list =
        (klass.instance_methods - EXCLUDE).map{|m| [m, klass.instance_method(m)] } +
        (klass.methods - EXCLUDE).map{|m| [".#{m}", klass.method(m) ]}
      list.select!{|name, method| method.source_location } if UnboundMethod.method_defined? :source_location
      to_hash(list)
    end

    CLASSES = [Array, Binding, Bignum, Dir, Comparable, Enumerable, FalseClass, Fixnum, Float, GC,
        Hash, Integer, IO, Kernel, Math, MatchData, Method, Module, NilClass, Numeric,
        ObjectSpace, Proc, Process, Range, Regexp, String, Struct, Symbol, TrueClass] +
      [ENV, ARGF].map{|obj| class << obj; self; end }

    case RUBY_VERSION
      when '1.8.6'
      when '1.8.7'
        CLASSES << Enumerable::Enumerator
      else
        CLASSES << Enumerator
    end

    def digest
      to_hash(
        CLASSES.map { |klass| [klass, class_signature(klass)] }
      )
    end

    def digest_delta(before, after)
      delta = {}
      before.each do |klass, methods|
        compare = after[klass]
        d = methods.map do |name, unbound|
          name unless unbound == compare[name]
        end + (compare.map(&:first) - methods.map(&:first))
        d.compact!
        delta[klass] = d unless d.empty?
      end
      delta unless delta.empty?
    end

    def lib_path(path)
      unless ENV['AUTOPKGTEST_TMP'].nil? # running under autopkgtest
        File.expand_path(File.join(Gem::Specification.find_by_name('backports').lib_dirs_glob, path), __FILE__)
      else
        File.expand_path("../../lib/#{path}", __FILE__)
      end
    end

    # Order super important!
    def test__1_abbrev_can_be_required_before_backports
      assert require('abbrev')
      assert !$LOADED_FEATURES.include?('backports')
    end

    # Order super important!
    def test__2_backports_wont_override_unnecessarily
      before = digest
      latest = "2.4.0"
      if RUBY_VERSION > '1.8.6'
        main_version = [RUBY_VERSION, latest].min
        unless File.exist?(lib_path("backports/#{main_version}.rb"))
          main_version = main_version.sub(/\.\d+$/, '.0')
        end
        require 'backports/tools/deprecation'
        Backports.warned = Hash.new(true)
        require "backports/#{main_version}"
        after = digest
        assert_nil digest_delta(before, after)
      end
      if RUBY_VERSION < latest
        require "backports"
        after = digest
        assert !digest_delta(before, after).nil?
      end
    end

    if RUBY_VERSION < '1.9.2' # this backport wouldn't be necessary otherwise
      def test_setlib_load_correctly_after_requiring_backports
        path = lib_path("backports/1.9.2/stdlib/matrix.rb")
        assert_equal false,  $LOADED_FEATURES.include?(path)
        assert_equal true,  require('matrix')
        assert_equal true,  $bogus.include?("matrix")
        assert_equal true,  $LOADED_FEATURES.include?(path)
        assert_equal false, require('matrix')
      end
    end

    def test_setlib_load_correctly_before_requiring_backports_test
      assert_equal true,  $bogus.include?("abbrev")
      path = lib_path("backports/2.0.0/stdlib/abbrev.rb")
      assert_equal true,  $LOADED_FEATURES.include?(path)
      assert_equal false, require('abbrev')
    end

    def test_backports_does_not_interfere_for_libraries_without_backports_test
      assert_equal true,  require('scanf')
      assert_equal false, require('scanf')
    end

    def test_load_correctly_new_libraries_test
      path = lib_path("backports/2.0.0/stdlib/fake_stdlib_lib.rb")
      assert_equal false, $LOADED_FEATURES.include?(path)
      assert_equal true,  require('fake_stdlib_lib')
      assert_equal true,  $LOADED_FEATURES.include?(path)
      assert_equal false, require('fake_stdlib_lib')
    end

    def test_no_warnings
      require 'ostruct'
      require 'set'
      require 'backports/1.8.7/array/each'
      require 'backports/1.8.7/enumerator/next'
      assert_equal 1, [1,2,3].each.next # [Bug #70]
    end
  end
end