gr8 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,277 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ###
4
+ ### $Release: 0.1.0 $
5
+ ### $Copyright: copyright(c) 2015 kuwata-lab.com all rights reserved $
6
+ ### $License: MIT License $
7
+ ###
8
+
9
+ require_relative "common"
10
+ require "oktest"
11
+
12
+
13
+ Oktest.scope do
14
+
15
+
16
+ topic Gr8::App do
17
+
18
+ fixture :app do
19
+ app = Gr8::App.new
20
+ app.instance_variable_set('@script_name', "gr8")
21
+ app
22
+ end
23
+
24
+ fixture :input_data do
25
+ <<END
26
+ Haruhi 100
27
+ Mikuru 80
28
+ Yuki 120
29
+ END
30
+ end
31
+
32
+
33
+ topic '#run()' do
34
+
35
+ spec "[!33bj3] option '-h', '--help': prints help message." do
36
+ |app|
37
+ expected = Gr8::HELP % {script: "gr8"}
38
+ #
39
+ status = nil
40
+ sout, serr = dummy_io { status = app.run("-h") }
41
+ ok {sout} == expected
42
+ ok {serr} == ""
43
+ ok {status} == 0
44
+ #
45
+ status = nil
46
+ sout, serr = dummy_io { status = app.run("--help") }
47
+ ok {sout} == expected
48
+ ok {serr} == ""
49
+ ok {status} == 0
50
+ end
51
+
52
+ spec "[!7dvjg] option '--doc': opens website with browser." do
53
+ skip_when true, "hard to test"
54
+ end
55
+
56
+ spec "[!2tfh5] option '-v', '--version': prints version string." do
57
+ |app|
58
+ expected = Gr8::VERSION + "\n"
59
+ #
60
+ status = nil
61
+ sout, serr = dummy_io { status = app.run("-v") }
62
+ ok {sout} == expected
63
+ ok {serr} == ""
64
+ ok {status} == 0
65
+ #
66
+ status = nil
67
+ sout, serr = dummy_io { status = app.run("--version") }
68
+ ok {sout} == expected
69
+ ok {serr} == ""
70
+ ok {status} == 0
71
+ end
72
+
73
+ spec "[!1s7wm] option '-r': requires libraries." do
74
+ |app|
75
+ ok {defined?(PStore)} == nil
76
+ ok {defined?(GetoptLong)} == nil
77
+ dummy_io { app.run("-r pstore,getoptlong", "map{|s| s}") }
78
+ ok {defined?(PStore)} == "constant"
79
+ ok {defined?(GetoptLong)} == "constant"
80
+ end
81
+
82
+ spec "[!7wqyh] prints error when no argument." do
83
+ |app|
84
+ status = nil
85
+ sout, serr = dummy_io { status = app.run() }
86
+ ok {sout} == ""
87
+ ok {serr} == "ERROR (gr8): argument required.\n"
88
+ ok {status} == 1
89
+ end
90
+
91
+ spec "[!bwiqv] prints error when too many argument." do
92
+ |app|
93
+ status = nil
94
+ sout, serr = dummy_io { status = app.run("a", "b") }
95
+ ok {sout} == ""
96
+ ok {serr} == "ERROR (gr8): too many arguments.\n"
97
+ ok {status} == 1
98
+ end
99
+
100
+ spec "[!r69d6] executes ruby code with $stdin.lazy as self." do
101
+ |app, input_data|
102
+ code = "map{|s| s.split()[1].to_i}.inject(0,:+)"
103
+ status = nil
104
+ sout, serr = dummy_io(input_data) { status = app.run(code) }
105
+ ok {sout} == "300\n"
106
+ ok {serr} == ""
107
+ ok {status} == 0
108
+ #
109
+ code = "self.is_a?(Enumerator::Lazy)"
110
+ sout, serr = dummy_io(input_data) { app.run(code) }
111
+ ok {sout} == "true\n"
112
+ end
113
+
114
+ spec "[!zcxh1] removes '\n' from each line automatically." do
115
+ |app, input_data|
116
+ expected = <<'END'
117
+ "Haruhi 100"
118
+ "Mikuru 80"
119
+ "Yuki 120"
120
+ END
121
+ code = "map{|s| s.inspect }"
122
+ sout, _ = dummy_io(input_data) { app.run(code) }
123
+ ok {sout} == expected
124
+ end
125
+
126
+ spec "[!i7npb] $1, $2, ... are available in grep() block argument." do
127
+ |app, input_data|
128
+ code = 'grep(/^(\w+)\s+(\d+)$/){$1}'
129
+ sout, _ = dummy_io(input_data) { app.run(code) }
130
+ ok {sout} == "Haruhi\nMikuru\nYuki\n"
131
+ #
132
+ code = 'grep(/^(\w+)\s+(\d+)$/){$2.to_i}.inject(0,:+)'
133
+ sout, _ = dummy_io(input_data) { app.run(code) }
134
+ ok {sout} == "300\n"
135
+ end
136
+
137
+ spec "[!vkt64] lines are chomped automatically in grep() if block is not given." do
138
+ |app, input_data|
139
+ code = 'grep(/\d+/).map{|s| s.inspect}'
140
+ sout, _ = dummy_io(input_data) { app.run(code) }
141
+ ok {sout} == <<'END'
142
+ "Haruhi 100"
143
+ "Mikuru 80"
144
+ "Yuki 120"
145
+ END
146
+ end
147
+
148
+ spec "[!8hk3g] option '-F': separates each line into array." do
149
+ |app|
150
+ input_data = "A:10:x\n" + "B:20:y\n" + "C:30:z\n"
151
+ code = "map{|s| s.inspect }"
152
+ status = nil
153
+ sout, serr = dummy_io(input_data) { status = app.run("-F:", code) }
154
+ ok {sout} == %Q`["A", "10", "x"]\n["B", "20", "y"]\n["C", "30", "z"]\n`
155
+ ok {serr} == ""
156
+ ok {status} == 0
157
+ end
158
+
159
+ spec "[!jt4y5] option '-F': separator is omissible." do
160
+ |app, input_data|
161
+ code = "map{|s| s.inspect }"
162
+ status = nil
163
+ sout, serr = dummy_io(input_data) { status = app.run("-F", code) }
164
+ ok {sout} == %Q`["Haruhi", "100"]\n["Mikuru", "80"]\n["Yuki", "120"]\n`
165
+ ok {serr} == ""
166
+ ok {status} == 0
167
+ end
168
+
169
+ spec "[!jo4gm] option '-F': error when invalid regular expression." do
170
+ |app, input_data|
171
+ code = "map{|s| s.inspect }"
172
+ status = nil
173
+ sout, serr = dummy_io(input_data) { status = app.run("-F[a-}", code) }
174
+ ok {sout} == ""
175
+ ok {serr} == "ERROR (gr8): invalid regular expression: -F[a-}\n"
176
+ ok {status} == 1
177
+ end
178
+
179
+ spec "[!vnwu6] option '-C': select colum." do
180
+ |app, input_data|
181
+ code = "map{|s| s.inspect }"
182
+ sout, serr = dummy_io(input_data) { app.run("-C2", code) }
183
+ ok {sout} == %Q`"100"\n"80"\n"120"\n`
184
+ ok {serr} == ""
185
+ end
186
+
187
+ spec "[!7ruq0] option -C: argument should be an integer." do
188
+ |app, input_data|
189
+ code = "map{|s| s.inspect }"
190
+ status = nil
191
+ sout, serr = dummy_io(input_data) { status = app.run("-Cx", code) }
192
+ ok {sout} == ""
193
+ ok {serr} == "ERROR (gr8): integer expected: -Cx\n"
194
+ ok {status} == 1
195
+ end
196
+
197
+ spec "[!6x3dp] option -C: argument should be >= 1." do
198
+ |app, input_data|
199
+ code = "map{|s| s.inspect }"
200
+ status = nil
201
+ sout, serr = dummy_io(input_data) { status = app.run("-C0", code) }
202
+ ok {sout} == ""
203
+ ok {serr} == "ERROR (gr8): column number should be >= 1: -C0\n"
204
+ ok {status} == 1
205
+ end
206
+
207
+ spec "[!hsvnd] prints nothing when result is nil." do
208
+ |app, input_data|
209
+ sout, serr = dummy_io(input_data) { app.run("nil") }
210
+ ok {sout} == ""
211
+ ok {serr} == ""
212
+ end
213
+
214
+ spec "[!eiaa6] prints each item when result is Enumerable." do
215
+ |app, input_data|
216
+ sout, serr = dummy_io(input_data) { app.run("[10, 20, 30]") }
217
+ ok {sout} == "10\n20\n30\n"
218
+ ok {serr} == ""
219
+ end
220
+
221
+ spec "[!6pfay] prints value when result is not nil nor Enumerable." do
222
+ |app, input_data|
223
+ sout, serr = dummy_io(input_data) { app.run("123") }
224
+ ok {sout} == "123\n"
225
+ ok {serr} == ""
226
+ end
227
+
228
+ spec "[!h5wln] returns 0 as status code when executed successfully." do
229
+ |app, input_data|
230
+ code = "map{|s| s.split[1]}.map(&:to_i).inject(0,:+)"
231
+ status = nil
232
+ sout, serr = dummy_io(input_data) { status = app.run(code) }
233
+ ok {status} == 0
234
+ ok {sout} == "300\n"
235
+ ok {serr} == ""
236
+ end
237
+
238
+ end
239
+
240
+
241
+ topic '#main()' do
242
+
243
+ spec "[!w9kb8] exit with status code 0 when executed successfully." do
244
+ |app|
245
+ skip_when true, "contains exit()"
246
+ end
247
+
248
+ spec "[!nbag1] exit with status code 1 when execution failed." do
249
+ |app|
250
+ skip_when true, "contains exit()"
251
+ end
252
+
253
+ end
254
+
255
+
256
+ topic '#parse_options()' do
257
+
258
+ spec "[!5efp5] returns Hash object containing command-line options." do
259
+ args = ["-h", "--version", "arg1", "arg2"]
260
+ opts = Gr8::App.new.__send__(:parse_options, args)
261
+ ok {opts}.is_a?(Hash)
262
+ ok {opts} == {help: true, version: true}
263
+ end
264
+
265
+ spec "[!wdzss] modifies args." do
266
+ args = ["-h", "--version", "arg1", "arg2"]
267
+ opts = Gr8::App.new.__send__(:parse_options, args)
268
+ ok {args} == ["arg1", "arg2"]
269
+ end
270
+
271
+ end
272
+
273
+
274
+ end
275
+
276
+
277
+ end
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ###
4
+ ### $Release: 0.1.0 $
5
+ ### $Copyright: copyright(c) 2015 kuwata-lab.com all rights reserved $
6
+ ### $License: MIT License $
7
+ ###
8
+
9
+ $: << File.dirname(__FILE__)
10
+
11
+ require "stringio"
12
+
13
+ $DONT_RUN_GR8_APP = true
14
+ unless defined?(Gr8)
15
+ File.class_eval do
16
+ load join(dirname(dirname(__FILE__)), "bin", "gr8")
17
+ end
18
+ end
19
+
20
+
21
+ def dummy_io(input=nil)
22
+ originals = [$stdin, $stdout, $stderr]
23
+ sin, sout, serr = StringIO.new(input.to_s), StringIO.new, StringIO.new
24
+ $stdin, $stdout, $stderr = sin, sout, serr
25
+ begin
26
+ yield
27
+ ensure
28
+ $stdin, $stdout, $stderr = originals
29
+ end
30
+ return sout.string, serr.string
31
+ end
@@ -0,0 +1,834 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ###
4
+ ### $Release: 0.1.0 $
5
+ ### $Copyright: copyright(c) 2015 kuwata-lab.com all rights reserved $
6
+ ### $License: MIT License $
7
+ ###
8
+
9
+ require_relative "common"
10
+ require "oktest"
11
+
12
+
13
+ Oktest.scope do
14
+
15
+
16
+ topic Enumerable do
17
+
18
+
19
+ topic '#transform()' do
20
+
21
+ spec "[!peitw] similar to map() or collect(), make each item as self in block." do
22
+ ok { (1..3).xf {|i| i*10 } } == [10, 20, 30]
23
+ ok { (1..3).xf {|i| self*10 } } == [10, 20, 30]
24
+ end
25
+
26
+ end
27
+
28
+
29
+ topic '#map()' do
30
+
31
+ spec "[!zfmcx] each item is available as self in block of map()." do
32
+ ok { (1..3).map {|i| i * 10} } == [10, 20, 30]
33
+ ok { (1..3).map {|i| self*10} } == [10, 20, 30]
34
+ end
35
+
36
+ end
37
+
38
+
39
+ topic '#select()' do
40
+
41
+ spec "[!41hap] each item is available as self in block of select()." do
42
+ ok { (1..5).select {|i| i % 2 == 0 } } == [2, 4]
43
+ ok { (1..5).select {|i| self % 2 == 0 } } == [2, 4]
44
+ end
45
+
46
+ end
47
+
48
+
49
+ topic '#sum()' do
50
+
51
+ spec "[!9izc1] returns sum of numbers." do
52
+ ok {[0, 10, 20, 30].sum} == 60
53
+ ok {[0, 10, 20, 30].sum}.is_a?(Fixnum)
54
+ ok {[0.0, 10, 20, 30].sum} == 60.0
55
+ ok {[0.0, 10, 20, 30].sum}.is_a?(Float)
56
+ end
57
+
58
+ end
59
+
60
+
61
+ topic '#sum_i()' do
62
+
63
+ spec "[!01ehd] returns sum of integers, converting values into integer." do
64
+ ok {["10", "20", "30"].sum_i} == 60
65
+ ok {["10", "20", "30"].sum_i}.is_a?(Fixnum)
66
+ ok {["10.0", "20.0", "30.0"].sum_i} == 60
67
+ ok {["10.0", "20.0", "30.0"].sum_i}.is_a?(Fixnum)
68
+ end
69
+
70
+ end
71
+
72
+
73
+ topic '#sum_f()' do
74
+
75
+ spec "[!kplnt] returns sum of floats, converting values into float." do
76
+ ok {["10.5", "20.5", "30.5"].sum_f} == 61.5
77
+ ok {["10.5", "20.5", "30.5"].sum_f}.is_a?(Float)
78
+ ok {["10", "20", "30"].sum_f} == 60.0
79
+ ok {["10", "20", "30"].sum_f}.is_a?(Float)
80
+ end
81
+
82
+ end
83
+
84
+
85
+ topic '#avg()' do
86
+
87
+ spec "[!pvi8h] returnns average of numbers." do
88
+ ok {[10, 20, 30].avg} == 20.0
89
+ end
90
+
91
+ spec "[!poidi] returns nil when no numbers." do
92
+ ok {[].avg} == nil
93
+ end
94
+
95
+ end
96
+
97
+
98
+ topic '#avg_i()' do
99
+
100
+ spec "[!btiat] returns average of numbers, converting values into integer." do
101
+ ok {["10", "20", "30"].avg_i} == 20.0
102
+ ok {["10.1", "20.2", "30.3"].avg_i} == 20.0
103
+ end
104
+
105
+ spec "[!892q9] returns nil when no numbers." do
106
+ ok {[].avg_i} == nil
107
+ end
108
+
109
+ end
110
+
111
+
112
+ topic '#avg_f()' do
113
+
114
+ spec "[!oqpmc] returns average of numbers, converting values into float." do
115
+ ok {["10", "20", "30"].avg_f} == 20.0
116
+ ok {["10.1", "20.2", "30.3"].avg_f} == 20.2
117
+ end
118
+
119
+ spec "[!9bckq] returns nil when no numbers." do
120
+ ok {[].avg_f} == nil
121
+ end
122
+
123
+ end
124
+
125
+
126
+ topic '#xsplit()' do
127
+
128
+ spec "[!1pz77] splits each lines with pattern." do
129
+ arr = [" A 10\n", " B 20\n", " C 30\n"]
130
+ ok {arr.xsplit} == [["A", "10"], ["B", "20"], ["C", "30"]]
131
+ arr = [" A: 10\n", " B: 20\n", " C: 30\n"]
132
+ ok {arr.xsplit(/:/)} == [[" A", " 10\n"], [" B", " 20\n"], [" C", " 30\n"]]
133
+ end
134
+
135
+ spec "[!wte7b] if block given, use its result as index." do
136
+ arr = [" A 10\n", " B 20\n", " C 30\n"]
137
+ ok {arr.xsplit{1}} == ["10", "20", "30"]
138
+ arr = [" A: 10\n", " B: 20\n", " C: 30\n"]
139
+ ok {arr.xsplit(/:/){0}} == [" A", " B", " C"]
140
+ end
141
+
142
+ end
143
+
144
+
145
+ topic '#sed()' do
146
+
147
+ spec "[!c7m34] replaces all patterns found in each line with str or block." do
148
+ arr = ["a100", "b200", "c300"]
149
+ ok {arr.sed(/0/, '*')} == ["a1*0", "b2*0", "c3*0"]
150
+ ok {arr.sed(/[a-z]/){|s| s.upcase}} == ["A100", "B200", "C300"]
151
+ end
152
+
153
+ end
154
+
155
+
156
+ topic '#gsed()' do
157
+
158
+ spec "[!9lzjv] replaces first pattern found in each line with str or block." do
159
+ arr = ["a100", "b200", "c300"]
160
+ ok {arr.gsed(/0/, '*')} == ["a1**", "b2**", "c3**"]
161
+ ok {arr.gsed(/[a-z]/){|s| s.upcase}} == ["A100", "B200", "C300"]
162
+ end
163
+
164
+ end
165
+
166
+
167
+ topic '#paths()' do
168
+
169
+ spec "[!t55ce] collects Pathname objects when block argument is not passed." do
170
+ arr = ["A.txt", "B.txt", "C.txt"]
171
+ ok {arr.paths}.all? {|x| x.is_a?(Pathname) }
172
+ end
173
+
174
+ spec "[!yjkm5] yields Pathname objects when block argument is passed." do
175
+ arr = ["A.txt", "B.txt", "C.txt"]
176
+ ok {arr.paths{|x| x.exist?}} == [false, false, false]
177
+ end
178
+
179
+ spec "[!4kppy] self is Patname object in block argument." do
180
+ arr = ["A.txt", "B.txt", "C.txt"]
181
+ ok {arr.paths{self.is_a?(Pathname)}}.all? {|x| x == true }
182
+ end
183
+
184
+ end
185
+
186
+
187
+ fixture :dummy_files do
188
+ pr = proc do
189
+ if File.directory?("_test.d")
190
+ Dir.glob("_test.d/**/*").each {|x| File.unlink(x) if File.file?(x) }
191
+ Dir.glob("_test.d/**/*").sort.reverse.each {|x| Dir.rmdir(x) }
192
+ Dir.rmdir("_test.d")
193
+ end
194
+ end
195
+ pr.call
196
+ at_end(&pr)
197
+ Dir.mkdir "_test.d"
198
+ Dir.mkdir "_test.d/src"
199
+ Dir.mkdir "_test.d/lib"
200
+ File.open("_test.d/src/file1.txt", "w") {|f| f.write("file1") }
201
+ File.open("_test.d/src/file2.txt", "w") {|f| f.write("file2") }
202
+ nil
203
+ end
204
+
205
+ def _write_file(filepath, content)
206
+ File.open(filepath, "w") {|f| f.write(content) }
207
+ end
208
+
209
+
210
+ topic '#edit()' do
211
+
212
+ spec "[!ur9mj] opens file with utf-8 encoding." do
213
+ |dummy_files|
214
+ files = Dir.glob("_test.d/src/*.txt")
215
+ arr = []
216
+ files.edit {|s|
217
+ arr << s.encoding.name
218
+ s
219
+ }
220
+ ok {arr} == ["UTF-8", "UTF-8"]
221
+ end
222
+
223
+ spec "[!qqegl] file content and file path are passed to block argument." do
224
+ |dummy_files|
225
+ files = Dir.glob("_test.d/src/*.txt")
226
+ arr = []
227
+ files.edit {|s, fpath| arr << fpath }
228
+ ok {arr} == files
229
+ end
230
+
231
+ spec "[!d8dxv] make content as self in block argument." do
232
+ |dummy_files|
233
+ files = Dir.glob("_test.d/src/*.txt")
234
+ arr = []
235
+ files.edit {|s| arr << (s.eql? self); s}
236
+ ok {arr} == [true, true]
237
+ end
238
+
239
+ spec "[!9g7re] edit file when content changed." do
240
+ |dummy_files|
241
+ files = Dir.glob("_test.d/src/*.txt")
242
+ ret = files.edit {|s|
243
+ s << "-homhom\n"
244
+ s
245
+ }
246
+ ok {ret} == [
247
+ "Edit: '_test.d/src/file1.txt'",
248
+ "Edit: '_test.d/src/file2.txt'",
249
+ ]
250
+ ok {File.read("_test.d/src/file1.txt")} == "file1-homhom\n"
251
+ ok {File.read("_test.d/src/file2.txt")} == "file2-homhom\n"
252
+ end
253
+
254
+ spec "[!exzkz] don't edit file when content not changed." do
255
+ |dummy_files|
256
+ files = Dir.glob("_test.d/src/*.txt")
257
+ ret = files.edit {|s|
258
+ s
259
+ }
260
+ ok {ret} == [
261
+ "NotChanged: '_test.d/src/file1.txt'",
262
+ "NotChanged: '_test.d/src/file2.txt'",
263
+ ]
264
+ ok {File.read("_test.d/src/file1.txt")} == "file1"
265
+ ok {File.read("_test.d/src/file2.txt")} == "file2"
266
+ end
267
+
268
+ spec "[!k9d31] skips if file not exist." do
269
+ |dummy_files|
270
+ files = Dir.glob("_test.d/src/*.txt").map{|x| x.sub(/\.txt/, '.tmp')}
271
+ ret = files.edit {|s|
272
+ s << "hom\n"
273
+ }
274
+ ok {ret} == [
275
+ "Skip: '_test.d/src/file1.tmp' does not exist.",
276
+ "Skip: '_test.d/src/file2.tmp' does not exist.",
277
+ ]
278
+ ok {"_test.d/src/file1.tmp"}.NOT.exist?
279
+ ok {"_test.d/src/file2.tmp"}.NOT.exist?
280
+ end
281
+
282
+ spec "[!6m49n] skips if file is not a file." do
283
+ |dummy_files|
284
+ files = ["_test.d/src", "_test.d/lib"]
285
+ ret = files.edit {|s|
286
+ s << "hom\n"
287
+ }
288
+ ok {ret} == [
289
+ "Skip: '_test.d/src' is not a file.",
290
+ "Skip: '_test.d/lib' is not a file.",
291
+ ]
292
+ end
293
+
294
+ end
295
+
296
+
297
+ topic '#edit_i()' do
298
+
299
+ spec "[!lpncu] creates backup file with suffix spedified." do
300
+ |dummy_files|
301
+ files = Dir.glob("_test.d/src/*.txt")
302
+ ret = files.edit_i(".bkup") {|s|
303
+ s << "hom\n"
304
+ }
305
+ ok {ret} == [
306
+ "Edit: '_test.d/src/file1.txt'",
307
+ "Edit: '_test.d/src/file2.txt'",
308
+ ]
309
+ ok {"_test.d/src/file1.txt"}.file_exist?
310
+ ok {"_test.d/src/file2.txt"}.file_exist?
311
+ ok {"_test.d/src/file1.txt.bkup"}.file_exist?
312
+ ok {"_test.d/src/file2.txt.bkup"}.file_exist?
313
+ end
314
+
315
+ end
316
+
317
+
318
+ topic '#move_to()' do
319
+
320
+ spec "[!n0ubo] block argument is required." do
321
+ pr = proc { ["file1"].move_to }
322
+ ok {pr}.raise?(ArgumentError, "move_to(): block argument required.")
323
+ end
324
+
325
+ spec "[!qqzqz] trims target file name." do
326
+ |dummy_files|
327
+ arr = [" _test.d/src/file1.txt\n", " _test.d/src/file2.txt\n"]
328
+ arr.move_to {"_test.d/lib"}
329
+ ok {"_test.d/lib/file1.txt"}.file_exist?
330
+ ok {"_test.d/lib/file2.txt"}.file_exist?
331
+ end
332
+
333
+ spec "[!nnud9] destination directory name is derived from target file name." do
334
+ |dummy_files|
335
+ Dir.mkdir("_test.d/lib1")
336
+ Dir.mkdir("_test.d/lib2")
337
+ Dir.glob("_test.d/src/*.txt").move_to {|s| s =~ /file(\d+)\.\w+$/; "_test.d/lib#{$1}" }
338
+ ok {"_test.d/lib/file1.txt"}.NOT.exist?
339
+ ok {"_test.d/lib/file2.txt"}.NOT.exist?
340
+ ok {"_test.d/lib1/file1.txt"}.file_exist?
341
+ ok {"_test.d/lib2/file2.txt"}.file_exist?
342
+ end
343
+
344
+ spec "[!n7a1q] prints target file and destination directory when verbose mode." do
345
+ |dummy_files|
346
+ ret = Dir.glob("_test.d/src/*.txt").move_to {"_test.d/lib"}
347
+ ok {ret} == [
348
+ "Move: '_test.d/src/file1.txt' => '_test.d/lib'",
349
+ "Move: '_test.d/src/file2.txt' => '_test.d/lib'",
350
+ ]
351
+ end
352
+
353
+ spec "[!ey3e4] if target directory name is nil or empty, skip moving file." do
354
+ |dummy_files|
355
+ expected = [
356
+ "Skip: target directory name is nil or empty (file: '_test.d/src/file1.txt')",
357
+ "Skip: target directory name is nil or empty (file: '_test.d/src/file2.txt')",
358
+ ]
359
+ ret = Dir.glob("_test.d/src/*.txt").move_to {""}
360
+ ok {ret} == expected
361
+ ret = Dir.glob("_test.d/src/*.txt").move_to {nil}
362
+ ok {ret} == expected
363
+ end
364
+
365
+ spec "[!i5jt6] if destination directory exists, move file to it." do
366
+ |dummy_files|
367
+ ret = Dir.glob("_test.d/src/*.txt").move_to {"_test.d/lib"}
368
+ ok {"_test.d/lib/file1.txt"}.file_exist?
369
+ ok {"_test.d/lib/file2.txt"}.file_exist?
370
+ end
371
+
372
+ spec "[!azqgk] if there is a file that name is same as desination directory, skip." do
373
+ |dummy_files|
374
+ Dir.rmdir("_test.d/lib")
375
+ File.open("_test.d/lib", "w") {|f| f.write("x") }
376
+ ret = Dir.glob("_test.d/src/*.txt").move_to {"_test.d/lib"}
377
+ ok {ret} == [
378
+ "Skip: directory '_test.d/lib' not a directory",
379
+ "Skip: directory '_test.d/lib' not a directory",
380
+ ]
381
+ end
382
+
383
+ spec "[!rqu5q] if destinatio directory doesn't exist, skip." do
384
+ |dummy_files|
385
+ Dir.rmdir("_test.d/lib")
386
+ ret = Dir.glob("_test.d/src/*.txt").move_to {"_test.d/lib"}
387
+ ok {ret} == [
388
+ "Skip: directory '_test.d/lib' not exist",
389
+ "Skip: directory '_test.d/lib' not exist",
390
+ ]
391
+ end
392
+
393
+ spec "[!0gq9h] if destination file already exist, skip." do
394
+ |dummy_files|
395
+ _write_file("_test.d/lib/file1.txt", "xxx")
396
+ _write_file("_test.d/lib/file2.txt", "yyy")
397
+ ret = Dir.glob("_test.d/src/*.txt").move_to {"_test.d/lib"}
398
+ ok {ret} == [
399
+ "Skip: destination file '_test.d/lib/file1.txt' already exist.",
400
+ "Skip: destination file '_test.d/lib/file2.txt' already exist.",
401
+ ]
402
+ ok {File.read("_test.d/lib/file1.txt")} == "xxx" # not overwritten
403
+ ok {File.read("_test.d/lib/file2.txt")} == "yyy" # not overwrirten
404
+ end
405
+
406
+ end
407
+
408
+
409
+ topic '#move_to!()' do
410
+
411
+ spec "[!40se5] block argument is required." do
412
+ pr = proc { ["file1"].move_to! }
413
+ ok {pr}.raise?(ArgumentError, "move_to!(): block argument required.")
414
+ end
415
+
416
+ spec "[!ebdqh] overwrite destination file even if it exists." do
417
+ |dummy_files|
418
+ _write_file("_test.d/lib/file1.txt", "xxx")
419
+ _write_file("_test.d/lib/file2.txt", "yyy")
420
+ ret = Dir.glob("_test.d/src/*.txt").move_to! {"_test.d/lib"}
421
+ ok {ret} == [
422
+ "Move!: '_test.d/src/file1.txt' => '_test.d/lib'",
423
+ "Move!: '_test.d/src/file2.txt' => '_test.d/lib'",
424
+ ]
425
+ ok {File.read("_test.d/lib/file1.txt")} == "file1" # overwritten
426
+ ok {File.read("_test.d/lib/file2.txt")} == "file2" # overwrirten
427
+ end
428
+
429
+ spec "[!itsh0] use 'Move!' instead of 'Move' when overwriting existing file." do
430
+ |dummy_files|
431
+ _write_file("_test.d/lib/file1.txt", "xxx")
432
+ _write_file("_test.d/lib/file2.txt", "yyy")
433
+ ret = Dir.glob("_test.d/src/*.txt").move_to! {"_test.d/lib"}
434
+ ok {ret} == [
435
+ "Move!: '_test.d/src/file1.txt' => '_test.d/lib'",
436
+ "Move!: '_test.d/src/file2.txt' => '_test.d/lib'",
437
+ ]
438
+ end
439
+
440
+ end
441
+
442
+
443
+ topic '#mkdir_and_move_to()' do
444
+
445
+ spec "[!k74dw] block argument is required." do
446
+ pr = proc { ["file1"].mkdir_and_move_to }
447
+ ok {pr}.raise?(ArgumentError, "mkdir_and_move_to(): block argument required.")
448
+ end
449
+
450
+ spec "[!b9d4m] if destination directory doesn't exist, creates it." do
451
+ |dummy_files|
452
+ files = Dir.glob("_test.d/src/*.txt")
453
+ ret = files.mkdir_and_move_to {|s| s =~ /file(\d+)/; "_test.d/lib#{$1}" }
454
+ ok {"_test.d/lib1/file1.txt"}.file_exist?
455
+ ok {"_test.d/lib2/file2.txt"}.file_exist?
456
+ ok {ret} == [
457
+ "Move: '_test.d/src/file1.txt' => '_test.d/lib1'",
458
+ "Move: '_test.d/src/file2.txt' => '_test.d/lib2'",
459
+ ]
460
+ end
461
+
462
+ end
463
+
464
+
465
+ topic '#mkdir_and_move_to!()' do
466
+
467
+ spec "[!z9yus] block argument is required." do
468
+ pr = proc { ["file1"].mkdir_and_move_to! }
469
+ ok {pr}.raise?(ArgumentError, "mkdir_and_move_to!(): block argument required.")
470
+ end
471
+
472
+ end
473
+
474
+
475
+ topic '#copy_to()' do
476
+
477
+ spec "[!fa5y0] copy files or directories into destination directory." do
478
+ |dummy_files|
479
+ files = Dir.glob("_test.d/src/*.txt")
480
+ ret = files.copy_to { "_test.d/lib" }
481
+ ok {ret} == [
482
+ "Copy: '_test.d/src/file1.txt' => '_test.d/lib'",
483
+ "Copy: '_test.d/src/file2.txt' => '_test.d/lib'",
484
+ ]
485
+ ok {"_test.d/src/file1.txt"}.file_exist?
486
+ ok {"_test.d/src/file2.txt"}.file_exist?
487
+ ok {"_test.d/lib/file1.txt"}.file_exist?
488
+ ok {"_test.d/lib/file2.txt"}.file_exist?
489
+ end
490
+
491
+ end
492
+
493
+
494
+ topic '#copy_to!()' do
495
+
496
+ end
497
+
498
+
499
+ topic '#mkdir_and_copy_to()' do
500
+
501
+ end
502
+
503
+
504
+ topic '#mkdir_and_copy_to!()' do
505
+
506
+ end
507
+
508
+
509
+ topic '#rename_as()' do
510
+
511
+ spec "[!ignfm] block argument is required." do
512
+ |dummy_files|
513
+ files = Dir.glob("_test.d/src/*.txt")
514
+ pr = proc {files.rename_as("_test.d/lib/file.txt")}
515
+ ok {pr}.raise?(ArgumentError, "rename_as(): block argument required.")
516
+ end
517
+
518
+ spec "[!qqzqz] trims target file name." do
519
+ |dummy_files|
520
+ files = Dir.glob("_test.d/src/*.txt").map {|s| " #{s}\n"}
521
+ files.rename_as{sub(/src/, 'lib')}
522
+ ok {"_test.d/src/file1.txt"}.NOT.exist?
523
+ ok {"_test.d/src/file2.txt"}.NOT.exist?
524
+ ok {"_test.d/lib/file1.txt"}.file_exist?
525
+ ok {"_test.d/lib/file2.txt"}.file_exist?
526
+ end
527
+
528
+ spec "[!nnud9] destination file name is derived from source file name." do
529
+ |dummy_files|
530
+ files = Dir.glob("_test.d/src/*.txt")
531
+ files.rename_as{sub(/\.txt$/, '.tmp')}
532
+ ok {"_test.d/src/file1.txt"}.NOT.exist?
533
+ ok {"_test.d/src/file2.txt"}.NOT.exist?
534
+ ok {"_test.d/src/file1.tmp"}.file_exist?
535
+ ok {"_test.d/src/file2.tmp"}.file_exist?
536
+ end
537
+
538
+ spec "[!dkejf] if target directory name is nil or empty, skips renaming file." do
539
+ |dummy_files|
540
+ files = Dir.glob("_test.d/src/*.txt")
541
+ ret = files.rename_as{nil}
542
+ ok {ret} == [
543
+ "Skip: target file name is nil or empty (file: '_test.d/src/file1.txt')",
544
+ "Skip: target file name is nil or empty (file: '_test.d/src/file2.txt')",
545
+ ]
546
+ ok {"_test.d/src/file1.txt"}.file_exist?
547
+ ok {"_test.d/src/file2.txt"}.file_exist?
548
+ #
549
+ ret = files.rename_as{""}
550
+ ok {ret} == [
551
+ "Skip: target file name is nil or empty (file: '_test.d/src/file1.txt')",
552
+ "Skip: target file name is nil or empty (file: '_test.d/src/file2.txt')",
553
+ ]
554
+ ok {"_test.d/src/file1.txt"}.file_exist?
555
+ ok {"_test.d/src/file2.txt"}.file_exist?
556
+ end
557
+
558
+ spec "[!8ap57] if target file or directory already exists, skips renaming files." do
559
+ |dummy_files|
560
+ files = Dir.glob("_test.d/src/*.txt")
561
+ _write_file("_test.d/lib/file1.txt", "xxx")
562
+ _write_file("_test.d/lib/file2.txt", "yyy")
563
+ ret = files.rename_as {sub(/src/, 'lib')}
564
+ ok {ret} == [
565
+ "Skip: target file '_test.d/lib/file1.txt' already exists.",
566
+ "Skip: target file '_test.d/lib/file2.txt' already exists.",
567
+ ]
568
+ ok {"_test.d/src/file1.txt"}.file_exist?
569
+ ok {"_test.d/src/file2.txt"}.file_exist?
570
+ ok {"_test.d/lib/file1.txt"}.file_exist?
571
+ ok {"_test.d/lib/file2.txt"}.file_exist?
572
+ end
573
+
574
+ spec "[!qhlc8] if directory of target file already exists, renames file." do
575
+ |dummy_files|
576
+ files = Dir.glob("_test.d/src/*.txt")
577
+ ret = files.rename_as {sub(/src/, 'lib').sub(/\.txt/, '.tmp')}
578
+ ok {ret} == [
579
+ "Rename: '_test.d/src/file1.txt' => '_test.d/lib/file1.tmp'",
580
+ "Rename: '_test.d/src/file2.txt' => '_test.d/lib/file2.tmp'",
581
+ ]
582
+ ok {"_test.d/src/file1.txt"}.NOT.exist?
583
+ ok {"_test.d/src/file2.txt"}.NOT.exist?
584
+ ok {"_test.d/lib/file1.tmp"}.file_exist?
585
+ ok {"_test.d/lib/file2.tmp"}.file_exist?
586
+ end
587
+
588
+ spec "[!gg9w1] if directory of target file not exist, skips renaming files." do
589
+ |dummy_files|
590
+ files = Dir.glob("_test.d/src/*.txt")
591
+ ret = files.rename_as {sub(/src/, 'var')}
592
+ ok {ret} == [
593
+ "Skip: directory of target file '_test.d/var/file1.txt' not exist.",
594
+ "Skip: directory of target file '_test.d/var/file2.txt' not exist.",
595
+ ]
596
+ ok {"_test.d/src/file1.txt"}.file_exist?
597
+ ok {"_test.d/src/file2.txt"}.file_exist?
598
+ ok {"_test.d/var/file1.txt"}.NOT.exist?
599
+ ok {"_test.d/var/file2.txt"}.NOT.exist?
600
+ end
601
+
602
+ spec "[!vt24y] prints target file and destination directory when verbose mode." do
603
+ |dummy_files|
604
+ files = Dir.glob("_test.d/src/*.txt")
605
+ ret = files.rename_as {sub(/src/, 'lib').sub(/.txt/, '.tmp')}
606
+ ok {ret} == [
607
+ "Rename: '_test.d/src/file1.txt' => '_test.d/lib/file1.tmp'",
608
+ "Rename: '_test.d/src/file2.txt' => '_test.d/lib/file2.tmp'",
609
+ ]
610
+ end
611
+
612
+ end
613
+
614
+
615
+ topic '#rename_as!()' do
616
+
617
+ spec "[!ignfm] block argument is required." do
618
+ |dummy_files|
619
+ files = Dir.glob("_test.d/src/*.txt")
620
+ pr = proc {files.rename_as!("_test.d/lib/file.txt")}
621
+ ok {pr}.raise?(ArgumentError, "rename_as!(): block argument required.")
622
+ end
623
+
624
+ spec "[!qqzqz] trims target file name." do
625
+ skip_when true, "(common to rename_as())"
626
+ end
627
+
628
+ spec "[!nnud9] destination file name is derived from source file name." do
629
+ skip_when true, "(common to rename_as())"
630
+ end
631
+
632
+ spec "[!dkejf] if target directory name is nil or empty, skips renaming file." do
633
+ skip_when true, "(common to rename_as())"
634
+ end
635
+
636
+ spec "[!1yzjd] if target file or directory already exists, removes it before renaming file." do
637
+ |dummy_files|
638
+ files = Dir.glob("_test.d/src/*.txt")
639
+ _write_file("_test.d/lib/file1.txt", "xxx")
640
+ _write_file("_test.d/lib/file2.txt", "yyy")
641
+ ret = files.rename_as! {sub(/src/, 'lib')}
642
+ ok {ret} == [
643
+ "Rename!: '_test.d/src/file1.txt' => '_test.d/lib/file1.txt'",
644
+ "Rename!: '_test.d/src/file2.txt' => '_test.d/lib/file2.txt'",
645
+ ]
646
+ ok {"_test.d/src/file1.txt"}.NOT.exist?
647
+ ok {"_test.d/src/file2.txt"}.NOT.exist?
648
+ ok {"_test.d/lib/file1.txt"}.file_exist?
649
+ ok {"_test.d/lib/file2.txt"}.file_exist?
650
+ end
651
+
652
+ spec "[!qhlc8] if directory of target file already exists, renames file." do
653
+ skip_when true, "(common to rename_as())"
654
+ end
655
+
656
+ spec "[!gg9w1] if directory of target file not exist, skips renaming files." do
657
+ skip_when true, "(common to rename_as())"
658
+ end
659
+
660
+ spec "[!vt24y] prints target file and destination directory when verbose mode." do
661
+ skip_when true, "(common to rename_as())"
662
+ end
663
+
664
+ spec "[!gd9j9] use 'Rename!' instead of 'Rename' when overwriting existing file." do
665
+ |dummy_files|
666
+ files = Dir.glob("_test.d/src/*.txt")
667
+ _write_file("_test.d/lib/file1.txt", "xxx")
668
+ _write_file("_test.d/lib/file2.txt", "yyy")
669
+ ret = files.rename_as! {sub(/src/, 'lib')}
670
+ ok {ret} == [
671
+ "Rename!: '_test.d/src/file1.txt' => '_test.d/lib/file1.txt'",
672
+ "Rename!: '_test.d/src/file2.txt' => '_test.d/lib/file2.txt'",
673
+ ]
674
+ end
675
+
676
+ end
677
+
678
+
679
+ topic '#mkdir_and_rename_as()' do
680
+
681
+ spec "[!ignfm] block argument is required." do
682
+ |dummy_files|
683
+ files = Dir.glob("_test.d/src/*.txt")
684
+ pr = proc {files.mkdir_and_rename_as("_test.d/lib/file.txt")}
685
+ ok {pr}.raise?(ArgumentError, "mkdir_and_rename_as(): block argument required.")
686
+ end
687
+
688
+ spec "[!qqzqz] trims target file name." do
689
+ skip_when true, "(common to rename_as())"
690
+ end
691
+
692
+ spec "[!nnud9] destination file name is derived from source file name." do
693
+ skip_when true, "(common to rename_as())"
694
+ end
695
+
696
+ spec "[!dkejf] if target directory name is nil or empty, skips renaming file." do
697
+ skip_when true, "(common to rename_as())"
698
+ end
699
+
700
+ spec "[!8ap57] if target file or directory already exists, skips renaming files." do
701
+ skip_when true, "(common to rename_as())"
702
+ end
703
+
704
+ spec "[!qhlc8] if directory of target file already exists, renames file." do
705
+ skip_when true, "(common to rename_as())"
706
+ end
707
+
708
+ spec "[!sh2ti] if directory of target file not exist, creates it." do
709
+ |dummy_files|
710
+ files = Dir.glob("_test.d/src/*.txt")
711
+ ret = files.mkdir_and_rename_as {sub(/src/, 'var/tmp').sub(/\.txt/, '.tmp')}
712
+ ok {ret} == [
713
+ "Rename: '_test.d/src/file1.txt' => '_test.d/var/tmp/file1.tmp'",
714
+ "Rename: '_test.d/src/file2.txt' => '_test.d/var/tmp/file2.tmp'",
715
+ ]
716
+ ok {"_test.d/src/file1.txt"}.NOT.exist?
717
+ ok {"_test.d/src/file2.txt"}.NOT.exist?
718
+ ok {"_test.d/var/tmp/file1.tmp"}.file_exist?
719
+ ok {"_test.d/var/tmp/file2.tmp"}.file_exist?
720
+ end
721
+
722
+ spec "[!vt24y] prints source and destination file path when verbose mode." do
723
+ skip_when true, "(common to rename_as())"
724
+ end
725
+
726
+ end
727
+
728
+
729
+ topic '#mkdir_and_rename_as!()' do
730
+
731
+ spec "[!ignfm] block argument is required." do
732
+ |dummy_files|
733
+ files = Dir.glob("_test.d/src/*.txt")
734
+ pr = proc {files.mkdir_and_rename_as!("_test.d/lib/file.txt")}
735
+ ok {pr}.raise?(ArgumentError, "mkdir_and_rename_as!(): block argument required.")
736
+ end
737
+
738
+ spec "[!qqzqz] trims target file name." do
739
+ skip_when true, "(common to rename_as())"
740
+ end
741
+
742
+ spec "[!nnud9] destination file name is derived from source file name." do
743
+ skip_when true, "(common to rename_as())"
744
+ end
745
+
746
+ spec "[!dkejf] if target directory name is nil or empty, skips renaming file." do
747
+ skip_when true, "(common to rename_as())"
748
+ end
749
+
750
+ spec "[!1yzjd] if target file or directory already exists, removes it before renaming file." do
751
+ skip_when true, "(common to rename_as!())"
752
+ end
753
+
754
+ spec "[!qhlc8] if directory of target file already exists, renames file." do
755
+ skip_when true, "(common to rename_as())"
756
+ end
757
+
758
+ spec "[!sh2ti] if directory of target file not exist, creates it." do
759
+ skip_when true, "(common to mkdir_and_rename_as())"
760
+ end
761
+
762
+ spec "[!vt24y] prints source and destination file path when verbose mode." do
763
+ skip_when true, "(common to rename_as())"
764
+ end
765
+
766
+ end
767
+
768
+
769
+ topic '#copy_as()' do
770
+
771
+ spec "[!0txp4] copy files or directories." do
772
+ |dummy_files|
773
+ files = Dir.glob("_test.d/src/*.txt")
774
+ ret = files.copy_as { sub(/src/, 'lib').sub(/\.txt$/, '.tmp') }
775
+ ok {ret} == [
776
+ "Copy: '_test.d/src/file1.txt' => '_test.d/lib/file1.tmp'",
777
+ "Copy: '_test.d/src/file2.txt' => '_test.d/lib/file2.tmp'",
778
+ ]
779
+ ok {"_test.d/src/file1.txt"}.file_exist?
780
+ ok {"_test.d/src/file2.txt"}.file_exist?
781
+ ok {"_test.d/lib/file1.tmp"}.file_exist?
782
+ ok {"_test.d/lib/file2.tmp"}.file_exist?
783
+ end
784
+
785
+ end
786
+
787
+
788
+ topic '#copy_as!()' do
789
+
790
+ end
791
+
792
+
793
+ topic '#mkdir_and_copy_as()' do
794
+
795
+ end
796
+
797
+
798
+ topic '#mkdir_and_copy_as!()' do
799
+
800
+ end
801
+
802
+
803
+ end
804
+
805
+
806
+ topic Enumerator::Lazy do
807
+
808
+
809
+ topic '#map()' do
810
+
811
+ spec "[!drgky] each item is available as self in block of map()." do
812
+ ok { (1..3).lazy.map {|i| i * 10 } }.is_a?(Enumerator::Lazy)
813
+ ok { (1..3).lazy.map {|i| i * 10 }.to_a } == [10, 20, 30]
814
+ ok { (1..3).lazy.map {|i| self*10}.to_a } == [10, 20, 30]
815
+ end
816
+
817
+ end
818
+
819
+
820
+ topic '#select()' do
821
+
822
+ spec "[!uhqz2] each item is available as self in block of map()." do
823
+ ok { (1..5).lazy.select {|i| i % 2 == 0 } }.is_a?(Enumerator::Lazy)
824
+ ok { (1..5).lazy.select {|i| i % 2 == 0 }.to_a } == [2, 4]
825
+ ok { (1..5).lazy.select {|i| self % 2 == 0 }.to_a } == [2, 4]
826
+ end
827
+
828
+ end
829
+
830
+
831
+ end
832
+
833
+
834
+ end