test_bench-isolated 0 → 2.0.0.1

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.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/lib/test_bench/isolated.rb +1 -0
  3. data/lib/test_bench_isolated/test_bench/cli.rb +298 -0
  4. data/lib/test_bench_isolated/test_bench/controls/file.rb +7 -0
  5. data/lib/test_bench_isolated/test_bench/controls/path.rb +7 -0
  6. data/lib/test_bench_isolated/test_bench/controls/random.rb +9 -0
  7. data/lib/test_bench_isolated/test_bench/controls/result.rb +7 -0
  8. data/lib/test_bench_isolated/test_bench/controls/stdin.rb +29 -0
  9. data/lib/test_bench_isolated/test_bench/controls.rb +11 -0
  10. data/lib/test_bench_isolated/test_bench/fixture/actuate/class.rb +97 -0
  11. data/lib/test_bench_isolated/test_bench/fixture/actuate/object.rb +93 -0
  12. data/lib/test_bench_isolated/test_bench/fixture/controls/exception.rb +9 -0
  13. data/lib/test_bench_isolated/test_bench/fixture/controls/fixture/class.rb +88 -0
  14. data/lib/test_bench_isolated/test_bench/fixture/controls/fixture/object/modules.rb +41 -0
  15. data/lib/test_bench_isolated/test_bench/fixture/controls/fixture/object.rb +33 -0
  16. data/lib/test_bench_isolated/test_bench/fixture/controls/fixture.rb +29 -0
  17. data/lib/test_bench_isolated/test_bench/fixture/controls/output.rb +9 -0
  18. data/lib/test_bench_isolated/test_bench/fixture/controls/random.rb +9 -0
  19. data/lib/test_bench_isolated/test_bench/fixture/controls/result.rb +9 -0
  20. data/lib/test_bench_isolated/test_bench/fixture/controls/title.rb +9 -0
  21. data/lib/test_bench_isolated/test_bench/fixture/controls.rb +13 -0
  22. data/lib/test_bench_isolated/test_bench/fixture/evaluate.rb +31 -0
  23. data/lib/test_bench_isolated/test_bench/fixture/fixture.rb +201 -0
  24. data/lib/test_bench_isolated/test_bench/fixture.rb +8 -0
  25. data/lib/test_bench_isolated/test_bench/output/controls/data.rb +51 -0
  26. data/lib/test_bench_isolated/test_bench/output/controls/device.rb +29 -0
  27. data/lib/test_bench_isolated/test_bench/output/controls/event.rb +9 -0
  28. data/lib/test_bench_isolated/test_bench/output/controls/output.rb +36 -0
  29. data/lib/test_bench_isolated/test_bench/output/controls/random.rb +9 -0
  30. data/lib/test_bench_isolated/test_bench/output/controls/style.rb +33 -0
  31. data/lib/test_bench_isolated/test_bench/output/controls/styling.rb +29 -0
  32. data/lib/test_bench_isolated/test_bench/output/controls/text.rb +19 -0
  33. data/lib/test_bench_isolated/test_bench/output/controls.rb +10 -0
  34. data/lib/test_bench_isolated/test_bench/output/device/null.rb +21 -0
  35. data/lib/test_bench_isolated/test_bench/output/device/substitute.rb +60 -0
  36. data/lib/test_bench_isolated/test_bench/output/digest.rb +115 -0
  37. data/lib/test_bench_isolated/test_bench/output/output.rb +68 -0
  38. data/lib/test_bench_isolated/test_bench/output/writer/buffer.rb +59 -0
  39. data/lib/test_bench_isolated/test_bench/output/writer/defaults.rb +13 -0
  40. data/lib/test_bench_isolated/test_bench/output/writer/style.rb +52 -0
  41. data/lib/test_bench_isolated/test_bench/output/writer/substitute.rb +40 -0
  42. data/lib/test_bench_isolated/test_bench/output/writer.rb +212 -0
  43. data/lib/test_bench_isolated/test_bench/output.rb +14 -0
  44. data/lib/test_bench_isolated/test_bench/random/controls/seed.rb +27 -0
  45. data/lib/test_bench_isolated/test_bench/random/controls.rb +1 -0
  46. data/lib/test_bench_isolated/test_bench/random/random.rb +170 -0
  47. data/lib/test_bench_isolated/test_bench/random.rb +1 -0
  48. data/lib/test_bench_isolated/test_bench/run/controls/directory.rb +72 -0
  49. data/lib/test_bench_isolated/test_bench/run/controls/event_data.rb +9 -0
  50. data/lib/test_bench_isolated/test_bench/run/controls/events/event_data.rb +11 -0
  51. data/lib/test_bench_isolated/test_bench/run/controls/events/file_crashed.rb +111 -0
  52. data/lib/test_bench_isolated/test_bench/run/controls/events/file_finished.rb +58 -0
  53. data/lib/test_bench_isolated/test_bench/run/controls/events/file_started.rb +49 -0
  54. data/lib/test_bench_isolated/test_bench/run/controls/events/finished.rb +58 -0
  55. data/lib/test_bench_isolated/test_bench/run/controls/events/session.rb +11 -0
  56. data/lib/test_bench_isolated/test_bench/run/controls/events/started.rb +49 -0
  57. data/lib/test_bench_isolated/test_bench/run/controls/exception.rb +103 -0
  58. data/lib/test_bench_isolated/test_bench/run/controls/executor.rb +58 -0
  59. data/lib/test_bench_isolated/test_bench/run/controls/file/create.rb +71 -0
  60. data/lib/test_bench_isolated/test_bench/run/controls/file/pattern.rb +35 -0
  61. data/lib/test_bench_isolated/test_bench/run/controls/file.rb +182 -0
  62. data/lib/test_bench_isolated/test_bench/run/controls/path.rb +17 -0
  63. data/lib/test_bench_isolated/test_bench/run/controls/process_id.rb +9 -0
  64. data/lib/test_bench_isolated/test_bench/run/controls/random.rb +9 -0
  65. data/lib/test_bench_isolated/test_bench/run/controls/result.rb +9 -0
  66. data/lib/test_bench_isolated/test_bench/run/controls/time.rb +9 -0
  67. data/lib/test_bench_isolated/test_bench/run/controls.rb +26 -0
  68. data/lib/test_bench_isolated/test_bench/run/events.rb +14 -0
  69. data/lib/test_bench_isolated/test_bench/run/executor/serial.rb +36 -0
  70. data/lib/test_bench_isolated/test_bench/run/executor/substitute.rb +47 -0
  71. data/lib/test_bench_isolated/test_bench/run/executor.rb +46 -0
  72. data/lib/test_bench_isolated/test_bench/run/file.rb +83 -0
  73. data/lib/test_bench_isolated/test_bench/run/get_files/substitute.rb +48 -0
  74. data/lib/test_bench_isolated/test_bench/run/get_files.rb +78 -0
  75. data/lib/test_bench_isolated/test_bench/run/output/file.rb +137 -0
  76. data/lib/test_bench_isolated/test_bench/run/output/summary/error.rb +141 -0
  77. data/lib/test_bench_isolated/test_bench/run/output/summary.rb +184 -0
  78. data/lib/test_bench_isolated/test_bench/run/run.rb +156 -0
  79. data/lib/test_bench_isolated/test_bench/run.rb +18 -0
  80. data/lib/test_bench_isolated/test_bench/session/controls/comment.rb +107 -0
  81. data/lib/test_bench_isolated/test_bench/session/controls/detail.rb +93 -0
  82. data/lib/test_bench_isolated/test_bench/session/controls/event.rb +9 -0
  83. data/lib/test_bench_isolated/test_bench/session/controls/events/commented.rb +112 -0
  84. data/lib/test_bench_isolated/test_bench/session/controls/events/context_finished.rb +72 -0
  85. data/lib/test_bench_isolated/test_bench/session/controls/events/context_skipped.rb +49 -0
  86. data/lib/test_bench_isolated/test_bench/session/controls/events/context_started.rb +66 -0
  87. data/lib/test_bench_isolated/test_bench/session/controls/events/detailed.rb +112 -0
  88. data/lib/test_bench_isolated/test_bench/session/controls/events/event_data.rb +11 -0
  89. data/lib/test_bench_isolated/test_bench/session/controls/events/failed.rb +49 -0
  90. data/lib/test_bench_isolated/test_bench/session/controls/events/fixture_finished.rb +55 -0
  91. data/lib/test_bench_isolated/test_bench/session/controls/events/fixture_started.rb +49 -0
  92. data/lib/test_bench_isolated/test_bench/session/controls/events/test_finished.rb +72 -0
  93. data/lib/test_bench_isolated/test_bench/session/controls/events/test_skipped.rb +49 -0
  94. data/lib/test_bench_isolated/test_bench/session/controls/events/test_started.rb +66 -0
  95. data/lib/test_bench_isolated/test_bench/session/controls/events.rb +35 -0
  96. data/lib/test_bench_isolated/test_bench/session/controls/exception.rb +47 -0
  97. data/lib/test_bench_isolated/test_bench/session/controls/failure.rb +21 -0
  98. data/lib/test_bench_isolated/test_bench/session/controls/fixture.rb +21 -0
  99. data/lib/test_bench_isolated/test_bench/session/controls/output/detail.rb +31 -0
  100. data/lib/test_bench_isolated/test_bench/session/controls/output.rb +57 -0
  101. data/lib/test_bench_isolated/test_bench/session/controls/process_id.rb +9 -0
  102. data/lib/test_bench_isolated/test_bench/session/controls/random.rb +9 -0
  103. data/lib/test_bench_isolated/test_bench/session/controls/result.rb +25 -0
  104. data/lib/test_bench_isolated/test_bench/session/controls/substitute/path.rb +35 -0
  105. data/lib/test_bench_isolated/test_bench/session/controls/time.rb +9 -0
  106. data/lib/test_bench_isolated/test_bench/session/controls/title.rb +41 -0
  107. data/lib/test_bench_isolated/test_bench/session/controls.rb +36 -0
  108. data/lib/test_bench_isolated/test_bench/session/events.rb +27 -0
  109. data/lib/test_bench_isolated/test_bench/session/output/get.rb +29 -0
  110. data/lib/test_bench_isolated/test_bench/session/output/writer/buffer/interactive/viewport.rb +167 -0
  111. data/lib/test_bench_isolated/test_bench/session/output/writer/buffer/interactive.rb +141 -0
  112. data/lib/test_bench_isolated/test_bench/session/output/writer/buffer.rb +29 -0
  113. data/lib/test_bench_isolated/test_bench/session/output/writer/defaults.rb +19 -0
  114. data/lib/test_bench_isolated/test_bench/session/output/writer/substitute.rb +19 -0
  115. data/lib/test_bench_isolated/test_bench/session/output/writer.rb +97 -0
  116. data/lib/test_bench_isolated/test_bench/session/output.rb +377 -0
  117. data/lib/test_bench_isolated/test_bench/session/projection.rb +30 -0
  118. data/lib/test_bench_isolated/test_bench/session/session.rb +220 -0
  119. data/lib/test_bench_isolated/test_bench/session/store.rb +61 -0
  120. data/lib/test_bench_isolated/test_bench/session/substitute/path.rb +65 -0
  121. data/lib/test_bench_isolated/test_bench/session/substitute/sink.rb +114 -0
  122. data/lib/test_bench_isolated/test_bench/session/substitute.rb +120 -0
  123. data/lib/test_bench_isolated/test_bench/session.rb +22 -0
  124. data/lib/test_bench_isolated/test_bench/telemetry/controls/event/event_data.rb +17 -0
  125. data/lib/test_bench_isolated/test_bench/telemetry/controls/event/metadata.rb +72 -0
  126. data/lib/test_bench_isolated/test_bench/telemetry/controls/event.rb +140 -0
  127. data/lib/test_bench_isolated/test_bench/telemetry/controls/event_data.rb +131 -0
  128. data/lib/test_bench_isolated/test_bench/telemetry/controls/file.rb +86 -0
  129. data/lib/test_bench_isolated/test_bench/telemetry/controls/handler.rb +83 -0
  130. data/lib/test_bench_isolated/test_bench/telemetry/controls/process_id.rb +21 -0
  131. data/lib/test_bench_isolated/test_bench/telemetry/controls/projection/receiver.rb +33 -0
  132. data/lib/test_bench_isolated/test_bench/telemetry/controls/projection.rb +86 -0
  133. data/lib/test_bench_isolated/test_bench/telemetry/controls/random.rb +9 -0
  134. data/lib/test_bench_isolated/test_bench/telemetry/controls/sink.rb +35 -0
  135. data/lib/test_bench_isolated/test_bench/telemetry/controls/time.rb +125 -0
  136. data/lib/test_bench_isolated/test_bench/telemetry/controls.rb +17 -0
  137. data/lib/test_bench_isolated/test_bench/telemetry/event.rb +108 -0
  138. data/lib/test_bench_isolated/test_bench/telemetry/event_data/serialization.rb +172 -0
  139. data/lib/test_bench_isolated/test_bench/telemetry/event_data.rb +15 -0
  140. data/lib/test_bench_isolated/test_bench/telemetry/sink/file.rb +33 -0
  141. data/lib/test_bench_isolated/test_bench/telemetry/sink/handler/event_registry.rb +44 -0
  142. data/lib/test_bench_isolated/test_bench/telemetry/sink/handler.rb +128 -0
  143. data/lib/test_bench_isolated/test_bench/telemetry/sink/projection.rb +134 -0
  144. data/lib/test_bench_isolated/test_bench/telemetry/sink.rb +13 -0
  145. data/lib/test_bench_isolated/test_bench/telemetry/substitute/sink.rb +85 -0
  146. data/lib/test_bench_isolated/test_bench/telemetry/substitute.rb +34 -0
  147. data/lib/test_bench_isolated/test_bench/telemetry/telemetry.rb +111 -0
  148. data/lib/test_bench_isolated/test_bench/telemetry.rb +17 -0
  149. data/lib/test_bench_isolated/test_bench/test_bench.rb +56 -0
  150. data/lib/test_bench_isolated/test_bench.rb +5 -0
  151. data/script/bench +5 -0
  152. metadata +157 -7
  153. data/lib/test_bench/bootstrap.rb +0 -328
@@ -0,0 +1,25 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ module Controls
5
+ module Result
6
+ def self.example
7
+ pass
8
+ end
9
+
10
+ def self.pass
11
+ true
12
+ end
13
+
14
+ def self.failure
15
+ false
16
+ end
17
+
18
+ def self.random
19
+ Random.boolean
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ module Controls
5
+ module Substitute
6
+ module Path
7
+ def self.example(segments=nil)
8
+ segments ||= Segment.examples
9
+
10
+ segments = segments.dup
11
+
12
+ path = TestBench::Session::Substitute::Path.new
13
+ path.segments = segments
14
+ path
15
+ end
16
+
17
+ module Segment
18
+ def self.examples
19
+ [example, Context.other_example, Test.example]
20
+ end
21
+
22
+ def self.example
23
+ Context.example
24
+ end
25
+
26
+ Test = Title::Test
27
+
28
+ Context = Title::Context
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ module Controls
5
+ Time = TestBench::Telemetry::Controls::Time
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,41 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ module Controls
5
+ module Title
6
+ module Context
7
+ def self.example
8
+ "Some Context"
9
+ end
10
+
11
+ def self.other_example
12
+ "Some Other Context"
13
+ end
14
+
15
+ def self.random
16
+ suffix = Random.string
17
+
18
+ "#{example} #{suffix}"
19
+ end
20
+ end
21
+
22
+ module Test
23
+ def self.example
24
+ "Some test"
25
+ end
26
+
27
+ def self.other_example
28
+ "Some other test"
29
+ end
30
+
31
+ def self.random
32
+ suffix = Random.string
33
+
34
+ "#{example} #{suffix}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_bench_isolated/test_bench/telemetry/controls'
2
+ require 'test_bench_isolated/test_bench/output/controls'
3
+
4
+ require 'test_bench_isolated/test_bench/session/controls/random'
5
+ require 'test_bench_isolated/test_bench/session/controls/time'
6
+ require 'test_bench_isolated/test_bench/session/controls/process_id'
7
+ require 'test_bench_isolated/test_bench/session/controls/result'
8
+ require 'test_bench_isolated/test_bench/session/controls/exception'
9
+
10
+ require 'test_bench_isolated/test_bench/session/controls/failure'
11
+ require 'test_bench_isolated/test_bench/session/controls/title'
12
+ require 'test_bench_isolated/test_bench/session/controls/exception'
13
+ require 'test_bench_isolated/test_bench/session/controls/comment'
14
+ require 'test_bench_isolated/test_bench/session/controls/detail'
15
+ require 'test_bench_isolated/test_bench/session/controls/fixture'
16
+
17
+ require 'test_bench_isolated/test_bench/session/controls/events/event_data'
18
+ require 'test_bench_isolated/test_bench/session/controls/events/failed'
19
+ require 'test_bench_isolated/test_bench/session/controls/events/context_started'
20
+ require 'test_bench_isolated/test_bench/session/controls/events/context_finished'
21
+ require 'test_bench_isolated/test_bench/session/controls/events/context_skipped'
22
+ require 'test_bench_isolated/test_bench/session/controls/events/test_started'
23
+ require 'test_bench_isolated/test_bench/session/controls/events/test_finished'
24
+ require 'test_bench_isolated/test_bench/session/controls/events/test_skipped'
25
+ require 'test_bench_isolated/test_bench/session/controls/events/commented'
26
+ require 'test_bench_isolated/test_bench/session/controls/events/detailed'
27
+ require 'test_bench_isolated/test_bench/session/controls/events/fixture_started'
28
+ require 'test_bench_isolated/test_bench/session/controls/events/fixture_finished'
29
+ require 'test_bench_isolated/test_bench/session/controls/events'
30
+
31
+ require 'test_bench_isolated/test_bench/session/controls/substitute/path'
32
+
33
+ require 'test_bench_isolated/test_bench/session/controls/event'
34
+
35
+ require 'test_bench_isolated/test_bench/session/controls/output'
36
+ require 'test_bench_isolated/test_bench/session/controls/output/detail'
@@ -0,0 +1,27 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ module Events
5
+ def self.each_type(&block)
6
+ constants(false).each(&block)
7
+ end
8
+
9
+ Failed = TestBench::Telemetry::Event.define(:message)
10
+
11
+ ContextStarted = TestBench::Telemetry::Event.define(:title)
12
+ ContextFinished = TestBench::Telemetry::Event.define(:title, :result)
13
+ ContextSkipped = TestBench::Telemetry::Event.define(:title)
14
+
15
+ TestStarted = TestBench::Telemetry::Event.define(:title)
16
+ TestFinished = TestBench::Telemetry::Event.define(:title, :result)
17
+ TestSkipped = TestBench::Telemetry::Event.define(:title)
18
+
19
+ Commented = TestBench::Telemetry::Event.define(:text, :quote, :heading)
20
+ Detailed = TestBench::Telemetry::Event.define(:text, :quote, :heading)
21
+
22
+ FixtureStarted = TestBench::Telemetry::Event.define(:name)
23
+ FixtureFinished = TestBench::Telemetry::Event.define(:name, :result)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ class Output
5
+ module Get
6
+ def self.call(substitute_session, styling: nil)
7
+ styling = true if styling.nil?
8
+
9
+ session_sink = substitute_session.sink
10
+
11
+ output = Output.new
12
+
13
+ if styling
14
+ output.writer.styling!
15
+ end
16
+
17
+ session_sink.records.each do |record|
18
+ event_data = record.event_data
19
+
20
+ output.receive(event_data)
21
+ end
22
+
23
+ output.writer.written_text
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,167 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ class Output
5
+ class Writer
6
+ module Buffer
7
+ class Interactive
8
+ Viewport = Struct.new(:width, :height, :row, :column, :scroll_rows, :rows_scrolled) do
9
+ def self.build(width, height, row, column, scroll_rows=nil)
10
+ scroll_rows ||= 0
11
+
12
+ rows_scrolled = 0
13
+
14
+ new(width, height, row, column, scroll_rows, rows_scrolled)
15
+ end
16
+
17
+ def self.null
18
+ build(0, 0, 0, 0)
19
+ end
20
+
21
+ def self.get
22
+ width, height, row, column = nil
23
+
24
+ Kernel.require 'io/console'
25
+ STDIN.raw do |stdin|
26
+ height, width = stdin.winsize
27
+
28
+ row, column = stdin.cursor
29
+ end
30
+
31
+ scroll_rows = row
32
+
33
+ build(width, height, row, column, scroll_rows)
34
+ end
35
+
36
+ def write(text)
37
+ bytes_written = 0
38
+
39
+ escape_sequence_pattern = self.class.escape_sequence_pattern
40
+
41
+ until text.empty?
42
+ write_text, escape_sequence, text = text.partition(escape_sequence_pattern)
43
+
44
+ bytes_written += write!(write_text)
45
+ bytes_written += escape_sequence.bytesize
46
+ end
47
+
48
+ bytes_written
49
+ end
50
+
51
+ def write!(text)
52
+ newline = text.end_with?("\n")
53
+
54
+ if newline
55
+ text = text[0...-1]
56
+ end
57
+
58
+ bytes_written = write_text(text)
59
+
60
+ if newline
61
+ bytes_written += write_newline
62
+ end
63
+
64
+ bytes_written
65
+ end
66
+
67
+ def write_text(text)
68
+ if text.start_with?("\e")
69
+ return text.bytesize
70
+ end
71
+
72
+ written_text = text[0...capacity]
73
+
74
+ bytes_written = written_text.bytesize
75
+
76
+ row = self.row
77
+ column = self.column
78
+
79
+ text_rows, text_columns = bytes_written.divmod(width)
80
+
81
+ row += text_rows
82
+
83
+ columns_remaining = width - column
84
+ if columns_remaining > text_columns
85
+ column += text_columns
86
+ else
87
+ row += 1
88
+ column = text_columns - columns_remaining
89
+ end
90
+
91
+ if row >= height
92
+ final_row = height - 1
93
+
94
+ scroll_rows = row - final_row
95
+ self.rows_scrolled += scroll_rows
96
+
97
+ row = final_row
98
+ end
99
+
100
+ self.row = row
101
+ self.column = column
102
+
103
+ bytes_written
104
+ end
105
+
106
+ def write_newline
107
+ if bottom_row?
108
+ if scroll_rows_remaining.zero?
109
+ return 0
110
+ end
111
+
112
+ self.rows_scrolled += 1
113
+ else
114
+ self.row += 1
115
+ end
116
+
117
+ self.column = 0
118
+
119
+ 1
120
+ end
121
+
122
+ def capacity?
123
+ if scroll_rows_remaining > 0
124
+ true
125
+ else
126
+ not bottom_row?
127
+ end
128
+ end
129
+
130
+ def capacity
131
+ capacity = 0
132
+
133
+ rows_remaining = height + scroll_rows_remaining - row - 1
134
+
135
+ if rows_remaining > 0
136
+ capacity += (rows_remaining - 1) * width
137
+
138
+ final_row = width - column
139
+ capacity += final_row
140
+ end
141
+
142
+ capacity
143
+ end
144
+
145
+ def scroll_rows_remaining
146
+ scroll_rows - rows_scrolled
147
+ end
148
+
149
+ def bottom_row?
150
+ row == height - 1
151
+ end
152
+
153
+ def self.escape_sequence_pattern
154
+ initiator = %r{\e\[}
155
+ terminator = %r{[[:alpha:]]}
156
+ sequence = %r{[[:digit:]]+(?:;[[:digit:]]+)*}
157
+
158
+ %r{#{initiator}#{sequence}?#{terminator}}
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,141 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ class Output
5
+ class Writer
6
+ module Buffer
7
+ class Interactive
8
+ attr_accessor :viewport
9
+
10
+ attr_accessor :raw_stderr
11
+
12
+ attr_accessor :stderr_pipe
13
+
14
+ def stderr_buffer
15
+ @stderr_buffer ||= String.new
16
+ end
17
+
18
+ def device
19
+ @device ||= TestBench::Output::Device::Substitute.build
20
+ end
21
+ attr_writer :device
22
+
23
+ attr_accessor :buffering
24
+ def buffering? = !!buffering
25
+
26
+ def self.build(device=nil)
27
+ device ||= Defaults.device
28
+
29
+ instance = new
30
+ instance.device = device
31
+ instance
32
+ end
33
+
34
+ def self.configure(receiver, device: nil, attr_name: nil)
35
+ attr_name ||= :buffer
36
+
37
+ instance = build(device)
38
+ receiver.public_send(:"#{attr_name}=", instance)
39
+ end
40
+
41
+ def receive(text)
42
+ if not cursor_saved?
43
+ save_cursor
44
+ end
45
+
46
+ bytes_written = viewport.write(text)
47
+
48
+ write_text = text.byteslice(0, bytes_written)
49
+ device.write(write_text)
50
+
51
+ if not viewport.capacity?
52
+ if not buffering?
53
+ buffering_message = "Output is buffering"
54
+
55
+ device.write("\e[0G\e[2m#{buffering_message}\e[22m")
56
+
57
+ self.buffering = true
58
+ end
59
+ end
60
+
61
+ update_stderr_buffer
62
+
63
+ bytes_written
64
+ end
65
+
66
+ def flush(*_devices)
67
+ if cursor_saved?
68
+ update_stderr_buffer
69
+ restore_cursor
70
+ end
71
+ end
72
+
73
+ def save_cursor
74
+ self.viewport = Viewport.get
75
+
76
+ self.raw_stderr = STDERR.dup
77
+
78
+ reader, writer = IO.pipe
79
+
80
+ new_stderr = writer
81
+ STDERR.reopen(new_stderr)
82
+
83
+ stderr_buffer.clear
84
+
85
+ self.stderr_pipe = reader
86
+
87
+ device.write("\e[s")
88
+ end
89
+
90
+ def restore_cursor
91
+ stderr_pipe.close
92
+
93
+ device.write("\e[u")
94
+
95
+ rows_scrolled = viewport.rows_scrolled
96
+
97
+ if not rows_scrolled.zero?
98
+ upward_movements = rows_scrolled
99
+ device.write("\e[#{upward_movements}F")
100
+ end
101
+
102
+ stderr_buffer.each_line do |line|
103
+ raw_stderr.write("\e[0K")
104
+ raw_stderr.write(line)
105
+ end
106
+
107
+ STDERR.reopen(raw_stderr)
108
+ self.raw_stderr = nil
109
+
110
+ self.viewport = nil
111
+ end
112
+
113
+ def update_stderr_buffer
114
+ loop do
115
+ stderr_text = stderr_pipe.read_nonblock(4096, exception: false)
116
+
117
+ if stderr_text == :wait_readable
118
+ break
119
+ end
120
+
121
+ viewport.write(stderr_text)
122
+
123
+ if not buffering?
124
+ raw_stderr.write(stderr_text)
125
+ end
126
+
127
+ self.stderr_buffer << stderr_text
128
+ end
129
+ end
130
+
131
+ def viewport?
132
+ !viewport.nil?
133
+ end
134
+ alias :cursor_saved? :viewport?
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,29 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ class Output
5
+ class Writer
6
+ module Buffer
7
+ def self.configure(receiver, device: nil, experimental_output: nil, attr_name: nil)
8
+ device ||= Defaults.device
9
+ experimental_output ||= Defaults.experimental_output
10
+ attr_name ||= :buffer
11
+
12
+ if experimental_output
13
+ interactive = device.tty?
14
+ else
15
+ interactive = false
16
+ end
17
+
18
+ if interactive
19
+ Buffer::Interactive.configure(receiver, device:, attr_name:)
20
+ else
21
+ TestBench::Output::Writer::Buffer.configure(receiver, attr_name:)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ class Output
5
+ class Writer
6
+ module Defaults
7
+ def self.device
8
+ TestBench::Output::Writer::Defaults.device
9
+ end
10
+
11
+ def self.experimental_output
12
+ ENV.fetch('TEST_BENCH_EXPERIMENTAL_OUTPUT', 'off') == 'on'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ class Output
5
+ class Writer
6
+ module Substitute
7
+ def self.build
8
+ Writer.build
9
+ end
10
+
11
+ class Writer < Writer
12
+ include TestBench::Output::Writer::Substitute
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,97 @@
1
+ module TestBenchIsolated
2
+ module TestBench
3
+ class Session
4
+ class Output
5
+ class Writer < TestBench::Output::Writer
6
+ attr_accessor :peer
7
+
8
+ def alternate_device
9
+ @alternate_device ||= TestBench::Output::Device::Substitute.build
10
+ end
11
+ attr_writer :alternate_device
12
+
13
+ def indentation_depth
14
+ @indentation_depth ||= 0
15
+ end
16
+ attr_writer :indentation_depth
17
+
18
+ def configure
19
+ device = self.device
20
+
21
+ self.alternate_device = TestBench::Output::Device::Null.build
22
+
23
+ Buffer.configure(self, device:)
24
+ end
25
+
26
+ def self.follow(previous_writer)
27
+ device = previous_writer
28
+
29
+ alternate_device = previous_writer.peer
30
+ alternate_device ||= TestBench::Output::Device::Null.build
31
+
32
+ previous_digest = previous_writer.digest
33
+ digest = previous_digest.clone
34
+
35
+ writer = new
36
+ writer.sync = false
37
+ writer.device = device
38
+ writer.alternate_device = alternate_device
39
+ writer.styling_policy = previous_writer.styling_policy
40
+ writer.digest = digest
41
+ writer.sequence = previous_writer.sequence
42
+ writer.column_sequence = previous_writer.column_sequence
43
+ writer.indentation_depth = previous_writer.indentation_depth
44
+ writer.digest = previous_writer.digest.clone
45
+ writer
46
+ end
47
+
48
+ def branch
49
+ alternate = self.class.follow(self)
50
+ primary = self.class.follow(self)
51
+
52
+ primary.peer = alternate
53
+
54
+ return primary, alternate
55
+ end
56
+
57
+ def indent
58
+ indentation = ' ' * indentation_depth
59
+
60
+ print(indentation)
61
+ end
62
+
63
+ def flush
64
+ buffer.flush(device, alternate_device)
65
+ end
66
+
67
+ def write!(data)
68
+ device.write(data)
69
+ alternate_device.write(data)
70
+ end
71
+
72
+ def increase_indentation
73
+ self.indentation_depth += 1
74
+ end
75
+ alias :indent! :increase_indentation
76
+
77
+ def decrease_indentation
78
+ self.indentation_depth -= 1
79
+ end
80
+ alias :deindent! :decrease_indentation
81
+
82
+ def follows?(other_writer)
83
+ if sequence < other_writer.sequence
84
+ false
85
+ elsif device == other_writer
86
+ true
87
+ elsif device == other_writer.peer
88
+ true
89
+ else
90
+ false
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end