tins 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.travis.yml +7 -0
- data/Gemfile +5 -0
- data/LICENSE +18 -0
- data/README.rdoc +20 -0
- data/Rakefile +28 -0
- data/TODO +1 -0
- data/VERSION +1 -0
- data/lib/spruz.rb +1 -0
- data/lib/tins.rb +34 -0
- data/lib/tins/alias.rb +1 -0
- data/lib/tins/attempt.rb +51 -0
- data/lib/tins/bijection.rb +46 -0
- data/lib/tins/count_by.rb +8 -0
- data/lib/tins/deep_dup.rb +11 -0
- data/lib/tins/file_binary.rb +85 -0
- data/lib/tins/generator.rb +68 -0
- data/lib/tins/go.rb +43 -0
- data/lib/tins/hash_symbolize_keys_recursive.rb +28 -0
- data/lib/tins/hash_union.rb +15 -0
- data/lib/tins/limited.rb +38 -0
- data/lib/tins/lines_file.rb +123 -0
- data/lib/tins/memoize.rb +78 -0
- data/lib/tins/minimize.rb +55 -0
- data/lib/tins/module_group.rb +13 -0
- data/lib/tins/null.rb +26 -0
- data/lib/tins/once.rb +25 -0
- data/lib/tins/p.rb +23 -0
- data/lib/tins/partial_application.rb +31 -0
- data/lib/tins/range_plus.rb +9 -0
- data/lib/tins/round.rb +51 -0
- data/lib/tins/secure_write.rb +25 -0
- data/lib/tins/shuffle.rb +17 -0
- data/lib/tins/string_camelize.rb +16 -0
- data/lib/tins/string_underscore.rb +15 -0
- data/lib/tins/string_version.rb +105 -0
- data/lib/tins/subhash.rb +42 -0
- data/lib/tins/time_dummy.rb +31 -0
- data/lib/tins/to_proc.rb +11 -0
- data/lib/tins/uniq_by.rb +10 -0
- data/lib/tins/version.rb +10 -0
- data/lib/tins/write.rb +19 -0
- data/lib/tins/xt.rb +25 -0
- data/lib/tins/xt/attempt.rb +7 -0
- data/lib/tins/xt/blank.rb +67 -0
- data/lib/tins/xt/count_by.rb +11 -0
- data/lib/tins/xt/deep_dup.rb +7 -0
- data/lib/tins/xt/file_binary.rb +7 -0
- data/lib/tins/xt/full.rb +33 -0
- data/lib/tins/xt/hash_symbolize_keys_recursive.rb +7 -0
- data/lib/tins/xt/hash_union.rb +11 -0
- data/lib/tins/xt/irb.rb +17 -0
- data/lib/tins/xt/named.rb +35 -0
- data/lib/tins/xt/null.rb +5 -0
- data/lib/tins/xt/p.rb +7 -0
- data/lib/tins/xt/partial_application.rb +11 -0
- data/lib/tins/xt/range_plus.rb +12 -0
- data/lib/tins/xt/round.rb +13 -0
- data/lib/tins/xt/secure_write.rb +11 -0
- data/lib/tins/xt/shuffle.rb +11 -0
- data/lib/tins/xt/string.rb +5 -0
- data/lib/tins/xt/string_camelize.rb +6 -0
- data/lib/tins/xt/string_underscore.rb +6 -0
- data/lib/tins/xt/string_version.rb +7 -0
- data/lib/tins/xt/subhash.rb +11 -0
- data/lib/tins/xt/symbol_to_proc.rb +7 -0
- data/lib/tins/xt/time_dummy.rb +7 -0
- data/lib/tins/xt/uniq_by.rb +15 -0
- data/lib/tins/xt/write.rb +11 -0
- data/tests/tins_file_binary_test.rb +67 -0
- data/tests/tins_lines_file_test.rb +84 -0
- data/tests/tins_memoize_test.rb +52 -0
- data/tests/tins_secure_write_test.rb +44 -0
- data/tests/tins_test.rb +629 -0
- data/tins.gemspec +35 -0
- metadata +212 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'tins'
|
5
|
+
|
6
|
+
module Tins
|
7
|
+
class TestTinsMemoize < Test::Unit::TestCase
|
8
|
+
class FooBar
|
9
|
+
def foo(*a)
|
10
|
+
@@foo ||= 0
|
11
|
+
@@foo += 1
|
12
|
+
end
|
13
|
+
memoize_method :foo
|
14
|
+
|
15
|
+
def bar(*a)
|
16
|
+
@@bar ||= 0
|
17
|
+
@@bar += 1
|
18
|
+
end
|
19
|
+
memoize_function :bar
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_foo
|
23
|
+
fb1 = FooBar.new
|
24
|
+
fb2 = FooBar.new
|
25
|
+
assert_equal 1, fb1.foo(1, 2)
|
26
|
+
assert_equal 2, fb2.foo(1, 2)
|
27
|
+
assert_equal 3, fb1.foo(1, 2, 3)
|
28
|
+
assert_equal 4, fb2.foo(1, 2, 3)
|
29
|
+
assert_equal 1, fb1.foo(1, 2)
|
30
|
+
assert_equal 2, fb2.foo(1, 2)
|
31
|
+
FooBar.memoize_cache_clear
|
32
|
+
assert_equal 5, fb1.foo(1, 2)
|
33
|
+
assert_equal 6, fb2.foo(1, 2)
|
34
|
+
assert_equal 5, fb1.foo(1, 2)
|
35
|
+
assert_equal 6, fb2.foo(1, 2)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_bar
|
39
|
+
fb1 = FooBar.new
|
40
|
+
fb2 = FooBar.new
|
41
|
+
assert_equal 1, fb1.bar(1, 2)
|
42
|
+
assert_equal 1, fb2.bar(1, 2)
|
43
|
+
assert_equal 2, fb1.bar(1, 2, 3)
|
44
|
+
assert_equal 2, fb2.bar(1, 2, 3)
|
45
|
+
assert_equal 1, fb1.bar(1, 2)
|
46
|
+
assert_equal 1, fb2.bar(1, 2)
|
47
|
+
FooBar.memoize_cache_clear
|
48
|
+
assert_equal 3, fb1.bar(1, 2)
|
49
|
+
assert_equal 3, fb2.bar(1, 2)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'tins'
|
6
|
+
|
7
|
+
module Tins
|
8
|
+
class TinsSecureWriteTest < Test::Unit::TestCase
|
9
|
+
module A
|
10
|
+
extend SecureWrite
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_secure_write
|
14
|
+
assert_equal 4, A.secure_write(fn = File.join(Dir.tmpdir, "A_file.#$$"), 'test')
|
15
|
+
assert_equal 4, A.secure_write(fn = File.join(Dir.tmpdir, "A_file.#$$")) { |f| f.write('test') }
|
16
|
+
assert_equal 'test', File.read(fn)
|
17
|
+
assert_raise(ArgumentError) { A.secure_write }
|
18
|
+
end
|
19
|
+
|
20
|
+
module B
|
21
|
+
extend Write
|
22
|
+
end
|
23
|
+
|
24
|
+
module C
|
25
|
+
def self.write(*args)
|
26
|
+
args
|
27
|
+
end
|
28
|
+
extend Write
|
29
|
+
end
|
30
|
+
|
31
|
+
class ::IO
|
32
|
+
extend Write
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_write
|
36
|
+
assert_equal 4, B.write(fn = File.join(Dir.tmpdir, "B_file.#$$"), 'test')
|
37
|
+
assert_equal 4, B.write(fn = File.join(Dir.tmpdir, "B_file.#$$")) { |f| f.write('test') }
|
38
|
+
assert_equal 4, IO.write(fn = File.join(Dir.tmpdir, "IO_file.#$$"), 'test')
|
39
|
+
assert_equal 'test', File.read(fn)
|
40
|
+
result = C.write(fn = File.join(Dir.tmpdir, "C_file.#$$"), 'test')
|
41
|
+
assert_equal [ fn, 'test' ], result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/tests/tins_test.rb
ADDED
@@ -0,0 +1,629 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'tins'
|
5
|
+
|
6
|
+
module Tins
|
7
|
+
class MinimizeTest < Test::Unit::TestCase
|
8
|
+
class ::Array
|
9
|
+
include Tins::Minimize
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_minimize
|
13
|
+
assert_equal [], [].minimize
|
14
|
+
assert_equal [ 1..1 ], [ 1 ].minimize
|
15
|
+
assert_equal [ 1..2 ], [ 1, 2 ].minimize
|
16
|
+
assert_equal [ 1..1, 7..7 ], [ 1, 7 ].minimize
|
17
|
+
assert_equal [ 1..3, 7..7, 11..14 ],
|
18
|
+
[ 1, 2, 3, 7, 11, 12, 13, 14 ].minimize
|
19
|
+
assert_equal [ 'A'..'C', 'G'..'G', 'K'..'M' ],
|
20
|
+
[ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_minimize!
|
24
|
+
assert_equal [], [].minimize!
|
25
|
+
assert_equal [ 1..1 ], [ 1 ].minimize!
|
26
|
+
assert_equal [ 1..2 ], [ 1, 2 ].minimize!
|
27
|
+
assert_equal [ 1..1, 7..7 ], [ 1, 7 ].minimize!
|
28
|
+
assert_equal [ 1..3, 7..7, 11..14 ],
|
29
|
+
[ 1, 2, 3, 7, 11, 12, 13, 14 ].minimize!
|
30
|
+
assert_equal [ 'A'..'C', 'G'..'G', 'K'..'M' ],
|
31
|
+
[ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize!
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_unminimize
|
35
|
+
assert_equal [], [].unminimize
|
36
|
+
assert_equal [ 1 ], [ 1..1 ].unminimize
|
37
|
+
assert_equal [ 1, 2 ], [ 1..2 ].unminimize
|
38
|
+
assert_equal [ 1, 7 ], [ 1..1, 7..7 ].unminimize
|
39
|
+
assert_equal [ 1, 2, 3, 7, 11, 12, 13, 14 ],
|
40
|
+
[ 1..3, 7..7, 11..14 ].unminimize
|
41
|
+
assert_equal [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ],
|
42
|
+
[ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_unminimize!
|
46
|
+
assert_equal [], [].unminimize!
|
47
|
+
assert_equal [ 1 ], [ 1..1 ].unminimize!
|
48
|
+
assert_equal [ 1, 2 ], [ 1..2 ].unminimize!
|
49
|
+
assert_equal [ 1, 7 ], [ 1..1, 7..7 ].unminimize!
|
50
|
+
assert_equal [ 1, 2, 3, 7, 11, 12, 13, 14 ],
|
51
|
+
[ 1..3, 7..7, 11..14 ].unminimize!
|
52
|
+
assert_equal [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ],
|
53
|
+
[ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class PartialApplicationTest < Test::Unit::TestCase
|
58
|
+
require 'tins/xt/partial_application'
|
59
|
+
|
60
|
+
def mul(x, y) x * y end
|
61
|
+
|
62
|
+
define_method(:dup) { |y| method(:mul).partial(2)[y] }
|
63
|
+
|
64
|
+
define_method(:trip) { |y| method(:mul).partial(3)[y] }
|
65
|
+
|
66
|
+
|
67
|
+
def test_proc
|
68
|
+
mul = lambda { |x, y| x * y }
|
69
|
+
klon = mul.partial
|
70
|
+
dup = mul.partial(2)
|
71
|
+
trip = mul.partial(3)
|
72
|
+
assert_equal [ 6, 9, 12 ], [ dup[3], trip[3], mul[4, 3] ]
|
73
|
+
assert_equal [ 6, 9, 12 ], [ dup[3], trip[3], klon[4, 3] ]
|
74
|
+
assert_raises(ArgumentError) do
|
75
|
+
mul.partial(1, 2, 3)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_method
|
80
|
+
assert_equal [ 6, 9, 12 ], [ dup(3), trip(3), mul(4, 3) ]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class GeneratorTest < Test::Unit::TestCase
|
85
|
+
def setup
|
86
|
+
@numeric = [ 1, 2, 3 ]
|
87
|
+
@string = %w[a b c]
|
88
|
+
@chars = 'abc'
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_generator
|
92
|
+
g = Tins::Generator[@numeric, @string]
|
93
|
+
assert_equal 2, g.size
|
94
|
+
g.add_dimension(@chars, :each_byte)
|
95
|
+
assert_equal 3, g.size
|
96
|
+
assert_equal\
|
97
|
+
[[1, "a", 97],
|
98
|
+
[1, "a", 98],
|
99
|
+
[1, "a", 99],
|
100
|
+
[1, "b", 97],
|
101
|
+
[1, "b", 98],
|
102
|
+
[1, "b", 99],
|
103
|
+
[1, "c", 97],
|
104
|
+
[1, "c", 98],
|
105
|
+
[1, "c", 99],
|
106
|
+
[2, "a", 97],
|
107
|
+
[2, "a", 98],
|
108
|
+
[2, "a", 99],
|
109
|
+
[2, "b", 97],
|
110
|
+
[2, "b", 98],
|
111
|
+
[2, "b", 99],
|
112
|
+
[2, "c", 97],
|
113
|
+
[2, "c", 98],
|
114
|
+
[2, "c", 99],
|
115
|
+
[3, "a", 97],
|
116
|
+
[3, "a", 98],
|
117
|
+
[3, "a", 99],
|
118
|
+
[3, "b", 97],
|
119
|
+
[3, "b", 98],
|
120
|
+
[3, "b", 99],
|
121
|
+
[3, "c", 97],
|
122
|
+
[3, "c", 98],
|
123
|
+
[3, "c", 99]], g.to_a
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class RoundTest < Test::Unit::TestCase
|
128
|
+
require 'tins/xt/round'
|
129
|
+
|
130
|
+
def test_standard
|
131
|
+
assert_equal(1, 1.round)
|
132
|
+
assert_equal(-1, -1.round)
|
133
|
+
assert_equal(2, 1.5.round)
|
134
|
+
assert_kind_of Integer, 1.5.round
|
135
|
+
assert_equal(-1, -1.4.round)
|
136
|
+
assert_equal(-2, -1.5.round)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_inclusion
|
140
|
+
assert_equal(10, 12.round(-1))
|
141
|
+
assert_kind_of Integer, 12.round(-1)
|
142
|
+
assert_equal(-10, -12.round(-1))
|
143
|
+
assert_raises(ArgumentError) { 12.round(-2) }
|
144
|
+
assert_raises(ArgumentError) { -12.round(-2) }
|
145
|
+
assert_in_delta(1.6, 1.55.round(1), 1E-1)
|
146
|
+
assert_kind_of Float, 1.55.round(1)
|
147
|
+
assert_equal(2, 1.55.round(0))
|
148
|
+
assert_in_delta(-1.5, -1.45.round(1), 1E-1)
|
149
|
+
assert_equal(-1, -1.45.round(0))
|
150
|
+
assert_in_delta(-1.6, -1.55.round(1), 1E-1)
|
151
|
+
assert_equal(-2, -1.55.round(0))
|
152
|
+
assert_in_delta(-1.55, -1.55.round(999), 1E-2)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
class ModuleGroupTest < Test::Unit::TestCase
|
157
|
+
MyClasses = Tins::ModuleGroup[ Array, String, Hash ]
|
158
|
+
|
159
|
+
def test_module_group
|
160
|
+
assert MyClasses === []
|
161
|
+
assert MyClasses === ""
|
162
|
+
assert MyClasses === {}
|
163
|
+
assert !(MyClasses === :nix)
|
164
|
+
case []
|
165
|
+
when MyClasses
|
166
|
+
assert true
|
167
|
+
when Array
|
168
|
+
assert false
|
169
|
+
end
|
170
|
+
case :nix
|
171
|
+
when MyClasses
|
172
|
+
assert false
|
173
|
+
when Array
|
174
|
+
assert false
|
175
|
+
when Symbol
|
176
|
+
assert true
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
class UniqByTest < Test::Unit::TestCase
|
182
|
+
require 'tins/xt/uniq_by'
|
183
|
+
|
184
|
+
class Point < Struct.new :x, :y
|
185
|
+
end
|
186
|
+
|
187
|
+
def test_uniq_by
|
188
|
+
assert_equal [ 1, 2, 3 ], [ 1, 2, 2, 3 ].uniq_by.sort
|
189
|
+
a = [ 1, 2, 2, 3 ]; a.uniq_by!
|
190
|
+
assert_equal [ 1, 2, 3 ], a.sort
|
191
|
+
p1 = Point.new 1, 2
|
192
|
+
p2 = Point.new 2, 2
|
193
|
+
p3 = Point.new 2, 2
|
194
|
+
p4 = Point.new 3, 3
|
195
|
+
a = [ p1, p2, p3, p4 ]
|
196
|
+
a_uniq = a.uniq_by { |p| p.y }
|
197
|
+
assert_equal 2, a_uniq.size
|
198
|
+
assert a_uniq.include?(p4)
|
199
|
+
assert [ p1, p2, p3 ].any? { |p| a_uniq.include? p }
|
200
|
+
a.uniq_by! { |p| p.y }
|
201
|
+
assert_equal 2, a.size
|
202
|
+
assert a.include?(p4)
|
203
|
+
assert [ p1, p2, p3 ].any? { |p| a.include? p }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
class CountByTest < Test::Unit::TestCase
|
208
|
+
require 'tins/xt/count_by'
|
209
|
+
|
210
|
+
def test_count_by
|
211
|
+
assert_equal 0, [].count_by { |x| x % 2 == 0 }
|
212
|
+
assert_equal 0, [ 1 ].count_by { |x| x % 2 == 0 }
|
213
|
+
assert_equal 1, [ 1 ].count_by { |x| x % 2 == 1 }
|
214
|
+
assert_equal 1, [ 1, 2 ].count_by { |x| x % 2 == 0 }
|
215
|
+
assert_equal 1, [ 1, 2 ].count_by { |x| x % 2 == 1 }
|
216
|
+
assert_equal 2, [ 1, 2, 3, 4, 5 ].count_by { |x| x % 2 == 0 }
|
217
|
+
assert_equal 3, [ 1, 2, 3, 4, 5 ].count_by { |x| x % 2 == 1 }
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
if Tins::Shuffle === Array
|
222
|
+
class ShuffleTest < Test::Unit::TestCase
|
223
|
+
require 'tins/xt/shuffle'
|
224
|
+
|
225
|
+
def setup
|
226
|
+
@a = [ 1, 2, 3 ]
|
227
|
+
srand 666
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_shuffle
|
231
|
+
assert_equal(a = [2, 3, 1], a = @a.shuffle)
|
232
|
+
assert_not_same @a, a
|
233
|
+
assert_equal(b = [3, 1, 2], b = @a.shuffle)
|
234
|
+
assert_not_same a, b
|
235
|
+
assert_not_same @a, b
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_shuffle_bang
|
239
|
+
assert_equal([2, 3, 1], a = @a.shuffle!)
|
240
|
+
assert_same @a, a
|
241
|
+
assert_equal([1, 2, 3], b = @a.shuffle!)
|
242
|
+
assert_same a, b
|
243
|
+
assert_same @a, b
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
class LimitedTest < Test::Unit::TestCase
|
249
|
+
class ::Array
|
250
|
+
include Tins::Shuffle
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_limited
|
254
|
+
count = {}
|
255
|
+
limited = Tins::Limited.new(5)
|
256
|
+
5.times do
|
257
|
+
limited.execute do
|
258
|
+
count[Thread.current] = true
|
259
|
+
sleep
|
260
|
+
end
|
261
|
+
end
|
262
|
+
until count.size >= 5
|
263
|
+
sleep 0.1
|
264
|
+
end
|
265
|
+
assert_equal 5, count.keys.uniq.size
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
class MemoizeTest < Test::Unit::TestCase
|
270
|
+
class A
|
271
|
+
def initialize(var)
|
272
|
+
@var = var
|
273
|
+
end
|
274
|
+
|
275
|
+
def foo(n)
|
276
|
+
r = n * @var
|
277
|
+
@var += 1
|
278
|
+
r
|
279
|
+
end
|
280
|
+
memoize_method :foo
|
281
|
+
|
282
|
+
def bar(n)
|
283
|
+
r = n * @var
|
284
|
+
@var += 1
|
285
|
+
r
|
286
|
+
end
|
287
|
+
memoize_function :bar
|
288
|
+
end
|
289
|
+
|
290
|
+
def setup
|
291
|
+
@a23 = A.new(23)
|
292
|
+
@a42 = A.new(42)
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_memoize_method
|
296
|
+
assert Module.__memoize_cache__.empty?
|
297
|
+
assert_equal 2 * 23, @a23.foo(2)
|
298
|
+
assert_equal 2 * 23, @a23.foo(2)
|
299
|
+
assert_equal 3 * 24, @a23.foo(3)
|
300
|
+
assert_equal 2 * 42, @a42.foo(2)
|
301
|
+
assert_equal 2 * 42, @a42.foo(2)
|
302
|
+
assert_equal 3 * 43, @a42.foo(3)
|
303
|
+
assert !Module.__memoize_cache__.empty?
|
304
|
+
@a23, @a42 = nil, nil
|
305
|
+
GC.start
|
306
|
+
# XXX test fails atm, assert Module.__memoize_cache__.empty?
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_memoize_function
|
310
|
+
assert A.__memoize_cache__.empty?
|
311
|
+
assert_equal 2 * 23, @a23.bar(2)
|
312
|
+
assert_equal 2 * 23, @a23.bar(2)
|
313
|
+
assert_equal 3 * 24, @a23.bar(3)
|
314
|
+
assert_equal 2 * 23, @a42.bar(2)
|
315
|
+
assert_equal 2 * 23, @a42.bar(2)
|
316
|
+
assert_equal 3 * 24, @a42.bar(3)
|
317
|
+
assert !A.__memoize_cache__.empty?
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
class HashUnionTest < Test::Unit::TestCase
|
322
|
+
require 'tins/xt/hash_union'
|
323
|
+
|
324
|
+
class HashLike1
|
325
|
+
def to_hash
|
326
|
+
{ 'foo' => true }
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
class HashLike2
|
331
|
+
def to_h
|
332
|
+
{ 'foo' => true }
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
def test_union
|
337
|
+
defaults = { 'foo' => true, 'bar' => false, 'quux' => nil }
|
338
|
+
hash = { 'foo' => false }
|
339
|
+
assert_equal [ ['bar', false], ['foo', false], ['quux', nil] ],
|
340
|
+
(hash | defaults).sort
|
341
|
+
hash |= defaults
|
342
|
+
assert_equal [ ['bar', false], ['foo', false], ['quux', nil] ],
|
343
|
+
hash.sort
|
344
|
+
hash = { 'foo' => false }
|
345
|
+
hash |= {
|
346
|
+
'quux' => true,
|
347
|
+
'baz' => 23,
|
348
|
+
} | defaults
|
349
|
+
assert_equal [ ['bar', false], [ 'baz', 23 ], ['foo', false],
|
350
|
+
['quux', true] ],
|
351
|
+
hash.sort
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_hash_conversion
|
355
|
+
assert_equal({ 'foo' => true }, { } | HashLike1.new)
|
356
|
+
assert_equal({ 'foo' => true }, { } | HashLike2.new)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
class HashSymbolizeKeysRecursiveTest < Test::Unit::TestCase
|
361
|
+
require 'tins/xt/hash_symbolize_keys_recursive'
|
362
|
+
|
363
|
+
def test_symbolize
|
364
|
+
hash = {
|
365
|
+
'key' => [
|
366
|
+
{
|
367
|
+
'key' => {
|
368
|
+
'key' => true
|
369
|
+
}
|
370
|
+
}
|
371
|
+
],
|
372
|
+
}
|
373
|
+
hash2 = hash.symbolize_keys_recursive
|
374
|
+
assert hash2[:key][0][:key][:key]
|
375
|
+
hash.symbolize_keys_recursive!
|
376
|
+
assert hash[:key][0][:key][:key]
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
class SubhashTest < Test::Unit::TestCase
|
381
|
+
require 'tins/xt/subhash'
|
382
|
+
|
383
|
+
def test_subhash
|
384
|
+
h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 }
|
385
|
+
assert_equal [ [ 'bar666', 666 ] ], h.subhash(/\Abar/).to_a
|
386
|
+
assert h.subhash(/\Abaz/).empty?
|
387
|
+
assert_equal [ [ 'foo1', 1 ], [ 'foo2', 2 ] ], h.subhash(/\Afoo\d/).to_a
|
388
|
+
assert_equal [ [ 'foo2', 2 ] ], h.subhash('foo2').to_a
|
389
|
+
end
|
390
|
+
|
391
|
+
def test_subhash_bang
|
392
|
+
h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 }
|
393
|
+
h.subhash!('foo2')
|
394
|
+
assert_equal [ [ 'foo2', 2 ] ], h.to_a
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_subhash_with_block
|
398
|
+
h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 }
|
399
|
+
assert h.subhash(/\Abaz/) { :foo }.empty?
|
400
|
+
assert_equal [ [ 'foo1', 1 ], [ 'foo2', 2 ] ],
|
401
|
+
h.subhash(/\Afoo(\d)/) { |_,_,m| Integer(m[1]) }.to_a
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
class NullTest < Test::Unit::TestCase
|
406
|
+
require 'tins/xt/null'
|
407
|
+
|
408
|
+
def test_null
|
409
|
+
assert_equal NULL, NULL.foo
|
410
|
+
assert_equal NULL, NULL.foo.bar
|
411
|
+
assert_equal 'NULL', NULL.inspect
|
412
|
+
assert_equal '', NULL.to_s
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
class TimeDummyTest < Test::Unit::TestCase
|
417
|
+
require 'tins/xt/time_dummy'
|
418
|
+
require 'time'
|
419
|
+
|
420
|
+
def test_time_dummy
|
421
|
+
time = Time.parse('2009-09-09 21:09:09')
|
422
|
+
assert_not_equal time, Time.now
|
423
|
+
Time.dummy = time
|
424
|
+
assert_equal time, Time.now
|
425
|
+
Time.dummy = nil
|
426
|
+
assert_not_equal time, Time.now
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
class BlankFullTest < Test::Unit::TestCase
|
431
|
+
require 'tins/xt/full'
|
432
|
+
require 'tins/xt/symbol_to_proc'
|
433
|
+
require 'set'
|
434
|
+
|
435
|
+
def test_blank
|
436
|
+
assert !true.blank?
|
437
|
+
assert false.blank?
|
438
|
+
assert nil.blank?
|
439
|
+
assert [].blank?
|
440
|
+
assert ![23].blank?
|
441
|
+
assert Set[].blank?
|
442
|
+
assert !Set[23].blank?
|
443
|
+
assert({}.blank?)
|
444
|
+
assert !{ :foo => 23 }.blank?
|
445
|
+
assert "".blank?
|
446
|
+
assert " ".blank?
|
447
|
+
assert !"foo".blank?
|
448
|
+
end
|
449
|
+
|
450
|
+
def test_full
|
451
|
+
assert_equal true, true.full?
|
452
|
+
assert_nil false.full?
|
453
|
+
assert_nil nil.full?
|
454
|
+
assert_nil [].full?
|
455
|
+
assert_equal [ 23 ], [ 23 ].full?
|
456
|
+
assert_nil Set[].full?
|
457
|
+
assert_equal Set[23], Set[23].full?
|
458
|
+
assert_nil({}.full?)
|
459
|
+
assert_equal({ :foo => 23 }, { :foo => 23 }.full?)
|
460
|
+
assert_nil "".full?
|
461
|
+
assert_nil " ".full?
|
462
|
+
assert_equal "foo", "foo".full?
|
463
|
+
assert_nil " ".full?(&:size)
|
464
|
+
assert_equal 3, "foo".full?(&:size)
|
465
|
+
assert_nil " ".full?(&:size)
|
466
|
+
assert_equal 3, "foo".full?(&:size)
|
467
|
+
assert_nil " ".full?(:size)
|
468
|
+
assert_equal 3, "foo".full?(:size)
|
469
|
+
assert_nil " ".full?(:size)
|
470
|
+
assert_equal 3, "foo".full?(:size)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
class BlankFullTest < Test::Unit::TestCase
|
475
|
+
require 'tins/xt/deep_dup'
|
476
|
+
|
477
|
+
def test_deep_dup
|
478
|
+
a = [1,2,3]
|
479
|
+
assert_equal a, a.deep_dup
|
480
|
+
assert_not_same a, a.deep_dup
|
481
|
+
end
|
482
|
+
|
483
|
+
def test_deep_dup_proc
|
484
|
+
f = lambda { |x| 2 * x }
|
485
|
+
g = f.deep_dup
|
486
|
+
assert_equal f[3], g[3]
|
487
|
+
assert_equal f, g
|
488
|
+
assert_same f, g
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
class BijectionTest < Test::Unit::TestCase
|
493
|
+
def test_bijection
|
494
|
+
assert_equal [ [ 1, 2 ], [ 3, 4 ] ], Tins::Bijection[ 1, 2, 3, 4 ].to_a.sort
|
495
|
+
assert_raise(ArgumentError) do
|
496
|
+
Tins::Bijection[1,2,3]
|
497
|
+
end
|
498
|
+
assert_raise(ArgumentError) do
|
499
|
+
Tins::Bijection[1,2,3,2]
|
500
|
+
end
|
501
|
+
assert_raise(ArgumentError) do
|
502
|
+
Tins::Bijection[1,2,1,3]
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
class TryTest < Test::Unit::TestCase
|
508
|
+
require 'tins/xt/attempt'
|
509
|
+
|
510
|
+
def test_attempt_block_condition
|
511
|
+
assert attempt(:attempts => 1, :exception_class => nil) { |c| c == 1 }
|
512
|
+
assert attempt(:attempts => 3, :exception_class => nil) { |c| c == 1 }
|
513
|
+
assert_equal false, attempt(:attempts => 3, :exception_class => nil) { |c| c == 4 }
|
514
|
+
assert_nil attempt(:attempts => 0, :exception_class => nil) { |c| c == 4 }
|
515
|
+
assert_raise(Exception) { attempt(:attempts => 3, :exception_class => nil) { raise Exception } }
|
516
|
+
end
|
517
|
+
|
518
|
+
class MyError < StandardError; end
|
519
|
+
class MyException < Exception; end
|
520
|
+
|
521
|
+
def test_attempt_default_exception
|
522
|
+
assert attempt(1) { |c| c != 1 and raise MyError }
|
523
|
+
assert attempt(3) { |c| c != 1 and raise MyError }
|
524
|
+
assert_equal false, attempt(3) { |c| c != 4 and raise MyError }
|
525
|
+
assert_nil attempt(0) { |c| c != 4 and raise MyError }
|
526
|
+
assert_raise(Exception) { attempt(3) { raise Exception } }
|
527
|
+
end
|
528
|
+
|
529
|
+
def test_attempt_exception
|
530
|
+
assert attempt(:attempts => 1, :exception_class => MyException) { |c| c != 1 and raise MyException }
|
531
|
+
assert attempt(:attempts => 3, :exception_class => MyException) { |c| c != 1 and raise MyException }
|
532
|
+
assert_equal false, attempt(:attempts => 3, :exception_class => MyException) { |c| c != 4 and raise MyException }
|
533
|
+
assert_nil attempt(:attempts => 0, :exception_class => MyException) { |c| c != 4 and raise MyException }
|
534
|
+
assert_raise(Exception) { attempt(:attempts => 3, :exception_class => MyException) { raise Exception } }
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
class RangePlustTest < Test::Unit::TestCase
|
539
|
+
require 'tins/xt/range_plus'
|
540
|
+
|
541
|
+
def test_range_plus
|
542
|
+
assert_equal [], (0...0) + (0...0)
|
543
|
+
assert_equal [ 0 ], (0..0) + (0...0)
|
544
|
+
assert_equal [ 0, 0 ], (0..0) + (0..0)
|
545
|
+
assert_equal((1..5).to_a, (1...3) + (3..5))
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
class NamedTest < Test::Unit::TestCase
|
550
|
+
require 'tins/xt/named'
|
551
|
+
|
552
|
+
def test_named_simple
|
553
|
+
a = [ 1, 2, 3 ]
|
554
|
+
a.named(:plus1, :map) { |x| x + 1 }
|
555
|
+
assert_equal [ 2, 3, 4 ], a.plus1
|
556
|
+
Array.named(:odd, :select) { |x| x % 2 == 1 }
|
557
|
+
assert_equal [ 3 ], a.plus1.odd
|
558
|
+
end
|
559
|
+
|
560
|
+
if RUBY_VERSION >= '1.9'
|
561
|
+
def foo(x, y, &block)
|
562
|
+
block.call x * y
|
563
|
+
end
|
564
|
+
|
565
|
+
def test_more_complex
|
566
|
+
Object.named(:foo_with_block, :foo) do |z|
|
567
|
+
z ** 2
|
568
|
+
end
|
569
|
+
assert_equal foo(2, 3) { |z| z ** 2 }, foo_with_block(2, 3)
|
570
|
+
Object.named(:foo_23, :foo, 2, 3)
|
571
|
+
assert_equal foo(2, 3) { |z| z ** 2 }, foo_23 { |z| z ** 2 }
|
572
|
+
Object.named(:foo_2, :foo, 2)
|
573
|
+
assert_equal foo(2, 3) { |z| z ** 2 }, foo_2(3) { |z| z ** 2 }
|
574
|
+
end
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
require 'tins/xt/string'
|
579
|
+
class StringCamelizeTest < Test::Unit::TestCase
|
580
|
+
def test_camelize
|
581
|
+
assert_equal 'FooBar', 'foo_bar'.camelize
|
582
|
+
assert_equal 'FooBar', 'foo_bar'.camelize(:upper)
|
583
|
+
assert_equal 'FooBar', 'foo_bar'.camelize(true)
|
584
|
+
assert_equal 'fooBar', 'foo_bar'.camelize(:lower)
|
585
|
+
assert_equal 'fooBar', 'foo_bar'.camelize(false)
|
586
|
+
assert_equal 'FooBar', 'foo_bar'.camelcase
|
587
|
+
assert_equal 'Foo::Bar', 'foo/bar'.camelize
|
588
|
+
assert_equal 'Foo::Bar', 'foo/bar'.camelize(:upper)
|
589
|
+
assert_equal 'Foo::Bar', 'foo/bar'.camelize(true)
|
590
|
+
assert_equal 'foo::Bar', 'foo/bar'.camelize(:lower)
|
591
|
+
assert_equal 'foo::Bar', 'foo/bar'.camelize(false)
|
592
|
+
assert_equal 'Foo::Bar', 'foo/bar'.camelcase
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
class StringUnderscoreTest < Test::Unit::TestCase
|
597
|
+
def test_underscore
|
598
|
+
assert_equal 'foo_bar', 'FooBar'.underscore
|
599
|
+
assert_equal 'foo/bar', 'Foo::Bar'.underscore
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
class StringVersionTest < Test::Unit::TestCase
|
604
|
+
def test_comparison
|
605
|
+
assert_operator '1.2'.version, :<, '1.3'.version
|
606
|
+
assert_operator '1.3'.version, :>, '1.2'.version
|
607
|
+
assert_operator '1.2'.version, :<=, '1.2'.version
|
608
|
+
assert_operator '1.2'.version, :>=, '1.2'.version
|
609
|
+
assert_operator '1.2'.version, :==, '1.2'.version
|
610
|
+
end
|
611
|
+
|
612
|
+
def test_change
|
613
|
+
s = '1.2'
|
614
|
+
s.version.revision = 1
|
615
|
+
assert_equal '1.2.0.1', s
|
616
|
+
s.version.revision += 1
|
617
|
+
assert_equal '1.2.0.2', s
|
618
|
+
s.version.succ!
|
619
|
+
assert_equal '1.2.0.3', s
|
620
|
+
s.version.pred!
|
621
|
+
assert_equal '1.2.0.2', s
|
622
|
+
assert_raise(ArgumentError) { s.version.build -= 1 }
|
623
|
+
s.version.major = 2
|
624
|
+
assert_equal '2.2.0.2', s
|
625
|
+
s.version.minor = 1
|
626
|
+
assert_equal '2.1.0.2', s
|
627
|
+
end
|
628
|
+
end
|
629
|
+
end
|