yamatanooroti 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -1
- data/lib/yamatanooroti/version.rb +1 -1
- data/lib/yamatanooroti/vterm.rb +24 -1
- data/lib/yamatanooroti/windows.rb +53 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 642a33b1504b4ecfdf9698597be8c5cff356950cfe71379cfb8c05ae6af45ec6
|
4
|
+
data.tar.gz: 8f4c37ab46ff74d2f14f4f2069c0b7c1847ea59c5d6b43990eaeff462c99474e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d017372f678c86f9e7f3dc0f6a6d96b4f26a0de534d96e508fe92b63e2ff129f2ae664dff1dcb4170aea0208420d014d5587ba66b6081c13d98713157f3a9c17
|
7
|
+
data.tar.gz: 77e04395752636618fd8202ccd8942440e7d5dfaa920d5650f60dd8b5ad4e83581d07297fcae62af46147ef063e25ee3ea0a2ab9531d840a2818d24a79c9fbeb
|
data/README.md
CHANGED
@@ -75,10 +75,24 @@ Likewise, you can specify Windows command prompt test by `Yamatanooroti::Windows
|
|
75
75
|
|
76
76
|
## Method Reference
|
77
77
|
|
78
|
-
### `start_terminal(height, width, command)`
|
78
|
+
### `start_terminal(height, width, command, startup_message: nil)`
|
79
79
|
|
80
80
|
Starts terminal internally that is sized `height` and `width` with `command` to test the result. The `command` should be an array of strings with a path of command and zero or more options. This should be called in `setup` method.
|
81
81
|
|
82
|
+
If `startup_message` is given, `start_terminal` waits for the string to be printed and then returns.
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
code = 'sleep 1; puts "aaa"; sleep 10; puts "bbb"'
|
86
|
+
start_terminal(5, 30, ['ruby', '-e', code], startup_message: 'aaa')
|
87
|
+
close
|
88
|
+
assert_screen(<<~EOC)
|
89
|
+
aaa
|
90
|
+
EOC
|
91
|
+
# The start_terminal method waits for the output of the "aaa" as specified by
|
92
|
+
# the startup_message option, the "bbb" after 10 seconds won't come because
|
93
|
+
# the I/O is closed immediately after it.
|
94
|
+
```
|
95
|
+
|
82
96
|
### `write(str)`
|
83
97
|
|
84
98
|
Writes `str` like inputting by a keyboard to the started terminal.
|
data/lib/yamatanooroti/vterm.rb
CHANGED
@@ -4,7 +4,7 @@ require 'pty'
|
|
4
4
|
require 'io/console'
|
5
5
|
|
6
6
|
module Yamatanooroti::VTermTestCaseModule
|
7
|
-
def start_terminal(height, width, command, wait: 0.1)
|
7
|
+
def start_terminal(height, width, command, wait: 0.1, startup_message: nil)
|
8
8
|
@wait = wait
|
9
9
|
@result = nil
|
10
10
|
|
@@ -16,6 +16,15 @@ module Yamatanooroti::VTermTestCaseModule
|
|
16
16
|
@screen = @vterm.screen
|
17
17
|
@screen.reset(true)
|
18
18
|
|
19
|
+
case startup_message
|
20
|
+
when String
|
21
|
+
@startup_message = ->(message) { message.start_with?(startup_message) }
|
22
|
+
when Regexp
|
23
|
+
@startup_message = ->(message) { startup_message.match?(message) }
|
24
|
+
else
|
25
|
+
@startup_message = nil
|
26
|
+
end
|
27
|
+
|
19
28
|
sync
|
20
29
|
end
|
21
30
|
|
@@ -30,20 +39,34 @@ module Yamatanooroti::VTermTestCaseModule
|
|
30
39
|
@pty_input.close
|
31
40
|
sync
|
32
41
|
Process.kill('KILL', @pid)
|
42
|
+
Process.waitpid(@pid)
|
33
43
|
end
|
34
44
|
|
35
45
|
private def sync
|
46
|
+
startup_message = '' if @startup_message
|
36
47
|
loop do
|
37
48
|
sleep @wait
|
38
49
|
chunk = @pty_output.read_nonblock(1024)
|
50
|
+
if @startup_message
|
51
|
+
startup_message << chunk
|
52
|
+
if @startup_message.(startup_message)
|
53
|
+
@startup_message = nil
|
54
|
+
chunk = startup_message
|
55
|
+
else
|
56
|
+
redo
|
57
|
+
end
|
58
|
+
end
|
39
59
|
@vterm.write(chunk)
|
40
60
|
chunk = @vterm.read
|
41
61
|
@pty_input.write(chunk)
|
42
62
|
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
|
63
|
+
retry if @startup_message
|
43
64
|
break
|
44
65
|
rescue Errno::EIO # EOF
|
66
|
+
retry if @startup_message
|
45
67
|
break
|
46
68
|
rescue IO::EAGAINWaitReadable # emtpy buffer
|
69
|
+
retry if @startup_message
|
47
70
|
break
|
48
71
|
end
|
49
72
|
end
|
@@ -289,8 +289,37 @@ module Yamatanooroti::WindowsTestCaseModule
|
|
289
289
|
end
|
290
290
|
end
|
291
291
|
|
292
|
+
private def quote_command_arg(arg)
|
293
|
+
if not arg.match?(/[ \t"]/)
|
294
|
+
# No quotation needed.
|
295
|
+
return arg
|
296
|
+
end
|
297
|
+
|
298
|
+
if not arg.match?(/["\\]/)
|
299
|
+
# No embedded double quotes or backlashes, so I can just wrap quote
|
300
|
+
# marks around the whole thing.
|
301
|
+
return %{"#{arg}"}
|
302
|
+
end
|
303
|
+
|
304
|
+
quote_hit = true
|
305
|
+
result = '"'
|
306
|
+
arg.chars.reverse.each do |c|
|
307
|
+
result << c
|
308
|
+
if quote_hit and c == '\\'
|
309
|
+
result << '\\'
|
310
|
+
elsif c == '"'
|
311
|
+
quote_hit = true
|
312
|
+
result << '\\'
|
313
|
+
else
|
314
|
+
quote_hit = false
|
315
|
+
end
|
316
|
+
end
|
317
|
+
result << '"'
|
318
|
+
result.reverse
|
319
|
+
end
|
320
|
+
|
292
321
|
private def launch(command)
|
293
|
-
command = %Q{cmd.exe /q /c "#{command
|
322
|
+
command = %Q{cmd.exe /q /c "#{command}"}
|
294
323
|
converted_command = mb2wc(command)
|
295
324
|
@pi = DL::PROCESS_INFORMATION.malloc
|
296
325
|
(@pi.to_ptr + 0)[0, DL::PROCESS_INFORMATION.size] = "\x00" * DL::PROCESS_INFORMATION.size
|
@@ -402,6 +431,12 @@ module Yamatanooroti::WindowsTestCaseModule
|
|
402
431
|
def close
|
403
432
|
sleep @wait
|
404
433
|
# read first before kill the console process including output
|
434
|
+
@result = retrieve_screen
|
435
|
+
|
436
|
+
free_resources
|
437
|
+
end
|
438
|
+
|
439
|
+
private def retrieve_screen
|
405
440
|
char_info_matrix = Fiddle::Pointer.to_ptr("\x00" * (DL::CHAR_INFO.size * (@height * @width)))
|
406
441
|
region = DL::SMALL_RECT.malloc
|
407
442
|
region.Left = 0
|
@@ -410,7 +445,7 @@ module Yamatanooroti::WindowsTestCaseModule
|
|
410
445
|
region.Bottom = @height
|
411
446
|
r = DL.ReadConsoleOutputW(@output_handle, char_info_matrix, @height * 65536 + @width, 0, region)
|
412
447
|
error_message(r, "ReadConsoleOutputW")
|
413
|
-
|
448
|
+
screen = []
|
414
449
|
prev_c = nil
|
415
450
|
@height.times do |y|
|
416
451
|
line = ''
|
@@ -425,10 +460,9 @@ module Yamatanooroti::WindowsTestCaseModule
|
|
425
460
|
prev_c = mb
|
426
461
|
end
|
427
462
|
end
|
428
|
-
|
463
|
+
screen << line.gsub(/ *$/, '')
|
429
464
|
end
|
430
|
-
|
431
|
-
free_resources
|
465
|
+
screen
|
432
466
|
end
|
433
467
|
|
434
468
|
def result
|
@@ -450,7 +484,20 @@ module Yamatanooroti::WindowsTestCaseModule
|
|
450
484
|
@wait = wait
|
451
485
|
@result = nil
|
452
486
|
setup_console(height, width)
|
453
|
-
launch(command.join(' '))
|
487
|
+
launch(command.map{ |c| quote_command_arg(c) }.join(' '))
|
488
|
+
case startup_message
|
489
|
+
when String
|
490
|
+
check_startup_message = ->(message) { message.start_with?(startup_message) }
|
491
|
+
when Regexp
|
492
|
+
check_startup_message = ->(message) { startup_message.match?(message) }
|
493
|
+
end
|
494
|
+
if check_startup_message
|
495
|
+
loop do
|
496
|
+
screen = retrieve_screen.join("\n").sub(/\n*\z/, "\n")
|
497
|
+
break if check_startup_message.(screen)
|
498
|
+
sleep @wait
|
499
|
+
end
|
500
|
+
end
|
454
501
|
end
|
455
502
|
end
|
456
503
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yamatanooroti
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- aycabta
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-unit
|
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
87
|
requirements: []
|
88
|
-
rubygems_version: 3.
|
88
|
+
rubygems_version: 3.0.3
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: Multi-platform real(?) terminal test framework
|