summaryrefslogtreecommitdiff
path: root/spec/ruby/core/module/ruby2_keywords_spec.rb
blob: 996774891c53426c15a02912043b4c58af9cd762 (plain)
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
require_relative '../../spec_helper'
require_relative 'fixtures/classes'

ruby_version_is "2.7" do
  describe "Module#ruby2_keywords" do
    it "marks the final hash argument as keyword hash" do
      obj = Object.new

      obj.singleton_class.class_exec do
        def foo(*a) a.last end
        ruby2_keywords :foo
      end

      last = obj.foo(1, 2, a: "a")
      Hash.ruby2_keywords_hash?(last).should == true
    end

    it "applies to the underlying method and applies across aliasing" do
      obj = Object.new

      obj.singleton_class.class_exec do
        def foo(*a) a.last end
        alias_method :bar, :foo
        ruby2_keywords :foo

        def baz(*a) a.last end
        ruby2_keywords :baz
        alias_method :bob, :baz
      end

      last = obj.foo(1, 2, a: "a")
      Hash.ruby2_keywords_hash?(last).should == true

      last = obj.bar(1, 2, a: "a")
      Hash.ruby2_keywords_hash?(last).should == true

      last = obj.baz(1, 2, a: "a")
      Hash.ruby2_keywords_hash?(last).should == true

      last = obj.bob(1, 2, a: "a")
      Hash.ruby2_keywords_hash?(last).should == true
    end

    ruby_version_is "2.7" ... "3.0" do
      it "fixes delegation warnings when calling a method accepting keywords" do
        obj = Object.new

        obj.singleton_class.class_exec do
          def foo(*a) bar(*a) end
          def bar(*a, **b) end
        end

        -> { obj.foo(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/)

        obj.singleton_class.class_exec do
          ruby2_keywords :foo
        end

        -> { obj.foo(1, 2, {a: "a"}) }.should_not complain
      end
    end

    it "returns nil" do
      obj = Object.new

      obj.singleton_class.class_exec do
        def foo(*a) end

        ruby2_keywords(:foo).should == nil
      end
    end

    it "raises NameError when passed not existing method name" do
      obj = Object.new

      -> {
        obj.singleton_class.class_exec do
          ruby2_keywords :not_existing
        end
      }.should raise_error(NameError, /undefined method `not_existing'/)
    end

    it "acceps String as well" do
      obj = Object.new

      obj.singleton_class.class_exec do
        def foo(*a) a.last end
        ruby2_keywords "foo"
      end

      last = obj.foo(1, 2, a: "a")
      Hash.ruby2_keywords_hash?(last).should == true
    end

    it "raises TypeError when passed not Symbol or String" do
      obj = Object.new

      -> {
        obj.singleton_class.class_exec do
          ruby2_keywords Object.new
        end
      }.should raise_error(TypeError, /is not a symbol nor a string/)
    end

    it "prints warning when a method does not accept argument splat" do
      obj = Object.new
      def obj.foo(a, b, c) end

      -> {
        obj.singleton_class.class_exec do
          ruby2_keywords :foo
        end
      }.should complain(/Skipping set of ruby2_keywords flag for/)
    end

    it "prints warning when a method accepts keywords" do
      obj = Object.new
      def obj.foo(a:, b:) end

      -> {
        obj.singleton_class.class_exec do
          ruby2_keywords :foo
        end
      }.should complain(/Skipping set of ruby2_keywords flag for/)
    end

    it "prints warning when a method accepts keyword splat" do
      obj = Object.new
      def obj.foo(**a) end

      -> {
        obj.singleton_class.class_exec do
          ruby2_keywords :foo
        end
      }.should complain(/Skipping set of ruby2_keywords flag for/)
    end
  end
end