|
1 | 1 | # frozen_string_literal: true
|
2 | 2 |
|
3 | 3 | RSpec.describe TypedStruct do
|
| 4 | + before { TypedStruct.default_keyword_init = nil } |
| 5 | + |
4 | 6 | it "helps avoid primitive obsession" do
|
5 | 7 | Price = TypedStruct.new(price: Rational) do
|
6 | 8 | %i[- + / *].each do |op|
|
|
28 | 30 | expect { y.int = "abc" }.to raise_error TypeError
|
29 | 31 | end
|
30 | 32 |
|
| 33 | + it "has default_keyword_init option" do |
| 34 | + attrs = RUBY_VERSION < "3.2" ? {int: {int: 5}} : {int: 5} |
| 35 | + |
| 36 | + TypedStruct.default_keyword_init = nil |
| 37 | + expect(TypedStruct.default_keyword_init).to be nil |
| 38 | + x = Struct.new(:int) |
| 39 | + y = TypedStruct.new(int: Rbs("untyped")) |
| 40 | + expect(x.new(int: 5)).to have_attributes attrs |
| 41 | + expect(y.new(int: 5)).to have_attributes attrs |
| 42 | + |
| 43 | + TypedStruct.default_keyword_init = true |
| 44 | + expect(TypedStruct.default_keyword_init).to be true |
| 45 | + x = Struct.new(:int, keyword_init: true) |
| 46 | + y = TypedStruct.new(int: Rbs("untyped")) |
| 47 | + expect(x.new(int: 5)).to have_attributes int: 5 |
| 48 | + expect(y.new(int: 5)).to have_attributes int: 5 |
| 49 | + |
| 50 | + TypedStruct.default_keyword_init = false |
| 51 | + expect(TypedStruct.default_keyword_init).to be false |
| 52 | + x = Struct.new(:int, keyword_init: false) |
| 53 | + y = TypedStruct.new(int: Rbs("untyped")) |
| 54 | + expect(x.new(int: 5)).to have_attributes int: {int: 5} |
| 55 | + expect(y.new(int: 5)).to have_attributes int: {int: 5} |
| 56 | + end |
| 57 | + |
31 | 58 | it "has an options attribute" do
|
32 | 59 | x = TypedStruct.new(int: Integer, str: String)
|
33 | 60 | expect(x.instance_variables).to contain_exactly :@options
|
|
45 | 72 | y = TypedStruct.new(int: Rbs("untyped"))
|
46 | 73 | attrs = RUBY_VERSION < "3.2" ? {int: {int: 5}} : {int: 5}
|
47 | 74 | expect(x.new(5)).to have_attributes int: 5
|
48 |
| - expect(x.new(int: 5)).to have_attributes attrs |
49 | 75 | expect(y.new(5)).to have_attributes int: 5
|
| 76 | + expect(x.new(int: 5)).to have_attributes attrs |
50 | 77 | expect(y.new(int: 5)).to have_attributes attrs
|
51 | 78 | x = Struct.new(:int, keyword_init: true)
|
52 | 79 | y = TypedStruct.new({ keyword_init: true }, int: Rbs("untyped"))
|
53 |
| - expect { x.new(5) }.to raise_error ArgumentError, "wrong number of arguments (given 1, expected 0)" |
54 |
| - expect { y.new(5) }.to raise_error ArgumentError, "wrong number of arguments (given 1, expected 0)" |
55 | 80 | expect(x.new(int: 5)).to have_attributes int: 5
|
56 | 81 | expect(y.new(int: 5)).to have_attributes int: 5
|
57 | 82 | end
|
|
71 | 96 |
|
72 | 97 | it "has identical error messages for presence checks" do
|
73 | 98 | x = Struct.new(:int, keyword_init: true)
|
74 |
| - expect { x.new(str: 5, abc: "xyz") }.to raise_error ArgumentError, "unknown keywords: str, abc" |
75 | 99 | y = TypedStruct.new({ keyword_init: true }, int: Integer)
|
| 100 | + expect { x.new(5) }.to raise_error ArgumentError, "wrong number of arguments (given 1, expected 0)" |
| 101 | + expect { y.new(5) }.to raise_error ArgumentError, "wrong number of arguments (given 1, expected 0)" |
| 102 | + expect { x.new(str: 5, abc: "xyz") }.to raise_error ArgumentError, "unknown keywords: str, abc" |
76 | 103 | expect { y.new(str: 5, abc: "xyz") }.to raise_error ArgumentError, "unknown keywords: str, abc"
|
77 | 104 | a = x.new(int: 5)
|
| 105 | + b = y.new(int: 5) |
78 | 106 | expect { a.str = 5 }.to raise_error NoMethodError, "undefined method `str=' for #<struct int=5>"
|
79 | 107 | expect { a[:str] = 5 }.to raise_error NameError, "no member 'str' in struct"
|
80 |
| - b = y.new(int: 5) |
81 | 108 | expect { b.str = 5 }.to raise_error NoMethodError, "undefined method `str=' for #<struct int=5>"
|
82 | 109 | expect { b[:str] = 5 }.to raise_error NameError, "no member 'str' in struct"
|
83 | 110 | x = Struct.new(:int)
|
|
89 | 116 | it "supports the same methods" do
|
90 | 117 | a = Struct.new(:str, :int)
|
91 | 118 | b = TypedStruct.new(str: String, int: Integer)
|
92 |
| - expect(a.public_methods).to contain_exactly *b.public_methods |
| 119 | + expect(a.public_methods).to contain_exactly *b.public_methods.grep_v(:default_keyword_init).grep_v(:default_keyword_init=) |
93 | 120 | expect(a.public_instance_methods).to contain_exactly *b.public_instance_methods.grep_v(:__class__)
|
94 | 121 | expect(a.public_instance_methods(false)).to contain_exactly *b.new("abc", 5).public_methods(false).grep_v(:[]=)
|
95 | 122 | end
|
|
0 commit comments