test_bench-output 2.0.0.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.
@@ -0,0 +1,266 @@
1
+ module TestBench
2
+ class Output
3
+ class Writer
4
+ attr_accessor :peer
5
+
6
+ def device
7
+ @device ||= Device::Substitute.build
8
+ end
9
+ attr_writer :device
10
+
11
+ def alternate_device
12
+ @alternate_device ||= Device::Substitute.build
13
+ end
14
+ attr_writer :alternate_device
15
+
16
+ def styling_policy
17
+ @styling_policy ||= Styling.default
18
+ end
19
+ alias :styling :styling_policy
20
+ attr_writer :styling_policy
21
+
22
+ def digest
23
+ @digest ||= Digest.new
24
+ end
25
+ attr_writer :digest
26
+
27
+ def sequence
28
+ @sequence ||= 0
29
+ end
30
+ attr_writer :sequence
31
+
32
+ def column_sequence
33
+ @column_sequence ||= 0
34
+ end
35
+ attr_writer :column_sequence
36
+
37
+ def indentation_depth
38
+ @indentation_depth ||= 0
39
+ end
40
+ attr_writer :indentation_depth
41
+
42
+ def buffer
43
+ @buffer ||= Buffer.new
44
+ end
45
+ attr_writer :buffer
46
+
47
+ def self.build(device=nil, styling: nil)
48
+ device ||= Defaults.device
49
+
50
+ instance = new
51
+
52
+ instance.device = device
53
+ instance.alternate_device = Device::Null.build
54
+
55
+ if device.tty?
56
+ Buffer::Console.configure(instance, device:)
57
+ else
58
+ instance.buffer.limit = 0
59
+ end
60
+
61
+ if not styling.nil?
62
+ instance.styling_policy = styling
63
+ end
64
+
65
+ instance
66
+ end
67
+
68
+ def self.configure(receiver, styling: nil, device: nil, attr_name: nil)
69
+ attr_name ||= :writer
70
+
71
+ instance = build(device, styling: styling)
72
+ receiver.public_send(:"#{attr_name}=", instance)
73
+ end
74
+
75
+ def sync
76
+ @sync.nil? ? @sync = true : @sync
77
+ end
78
+
79
+ def self.follow(previous_writer)
80
+ device = previous_writer
81
+
82
+ alternate_device = previous_writer.peer
83
+ alternate_device ||= Device::Null.build
84
+
85
+ previous_digest = previous_writer.digest
86
+ digest = previous_digest.clone
87
+
88
+ writer = new
89
+ writer.sync = false
90
+ writer.device = device
91
+ writer.alternate_device = alternate_device
92
+ writer.styling_policy = previous_writer.styling_policy
93
+ writer.digest = digest
94
+ writer.sequence = previous_writer.sequence
95
+ writer.column_sequence = previous_writer.column_sequence
96
+ writer.indentation_depth = previous_writer.indentation_depth
97
+ writer.digest = previous_writer.digest.clone
98
+ writer
99
+ end
100
+
101
+ def branch
102
+ alternate = self.class.follow(self)
103
+ primary = self.class.follow(self)
104
+
105
+ primary.peer = alternate
106
+
107
+ return primary, alternate
108
+ end
109
+
110
+ def puts(text=nil)
111
+ if column_sequence.zero?
112
+ indent
113
+ end
114
+
115
+ if not text.nil?
116
+ print(text)
117
+ end
118
+
119
+ style(:reset)
120
+
121
+ if tty?
122
+ write("\e[0K")
123
+ end
124
+
125
+ write("\n")
126
+
127
+ self.column_sequence = 0
128
+ end
129
+
130
+ def style(style, *additional_styles)
131
+ styles = [style, *additional_styles]
132
+
133
+ control_codes = styles.map do |style|
134
+ Style.control_code(style)
135
+ end
136
+
137
+ if styling?
138
+ write("\e[#{control_codes.join(';')}m")
139
+ end
140
+
141
+ self
142
+ end
143
+
144
+ def indent
145
+ indentation = ' ' * indentation_depth
146
+
147
+ print(indentation)
148
+ end
149
+
150
+ def print(text)
151
+ text = text.dump[1...-1]
152
+
153
+ self.column_sequence += text.length
154
+
155
+ write(text)
156
+
157
+ self
158
+ end
159
+
160
+ def write(data)
161
+ if sync
162
+ device.write(data)
163
+ alternate_device.write(data)
164
+
165
+ bytes_written = data.bytesize
166
+ else
167
+ bytes_written = buffer.receive(data)
168
+ end
169
+
170
+ self.sequence += bytes_written
171
+
172
+ data = data[0...bytes_written]
173
+ digest.update(data)
174
+
175
+ bytes_written
176
+ end
177
+
178
+ def tty?
179
+ device.tty?
180
+ end
181
+
182
+ def flush
183
+ buffer.flush(device, alternate_device)
184
+ end
185
+
186
+ def sync=(sync)
187
+ @sync = sync
188
+
189
+ if sync
190
+ flush
191
+ end
192
+ end
193
+
194
+ def written?(data=nil)
195
+ if data.nil?
196
+ sequence > 0
197
+ else
198
+ digest.digest?(data)
199
+ end
200
+ end
201
+
202
+ def current?(sequence)
203
+ sequence >= self.sequence
204
+ end
205
+
206
+ def increase_indentation
207
+ self.indentation_depth += 1
208
+ end
209
+ alias :indent! :increase_indentation
210
+
211
+ def decrease_indentation
212
+ self.indentation_depth -= 1
213
+ end
214
+ alias :deindent! :decrease_indentation
215
+
216
+ def follows?(other_writer)
217
+ if sequence < other_writer.sequence
218
+ false
219
+ elsif device == other_writer
220
+ true
221
+ elsif device == other_writer.peer
222
+ true
223
+ else
224
+ false
225
+ end
226
+ end
227
+
228
+ def styling?
229
+ Styling.styling?(styling_policy, device.tty?)
230
+ end
231
+
232
+ module Styling
233
+ Error = Class.new(RuntimeError)
234
+
235
+ def self.styling?(policy, console)
236
+ case policy
237
+ when on
238
+ true
239
+ when off
240
+ false
241
+ when detect
242
+ console ? true : false
243
+ else
244
+ raise Error, "Unknown styling policy #{policy.inspect}"
245
+ end
246
+ end
247
+
248
+ def self.on = :on
249
+ def self.off = :off
250
+ def self.detect = :detect
251
+
252
+ def self.default
253
+ policy = ENV.fetch('TEST_BENCH_OUTPUT_STYLING') do
254
+ return default!
255
+ end
256
+
257
+ policy.to_sym
258
+ end
259
+
260
+ def self.default!
261
+ :detect
262
+ end
263
+ end
264
+ end
265
+ end
266
+ end
@@ -0,0 +1,17 @@
1
+ require 'io/console'
2
+
3
+ require 'test_bench/session'
4
+
5
+ require 'test_bench/output/digest'
6
+
7
+ require 'test_bench/output/device/null'
8
+ require 'test_bench/output/device/substitute'
9
+
10
+ require 'test_bench/output/writer/buffer'
11
+ require 'test_bench/output/writer/buffer/console'
12
+ require 'test_bench/output/writer/defaults'
13
+ require 'test_bench/output/writer'
14
+ require 'test_bench/output/writer/style'
15
+ require 'test_bench/output/writer/substitute'
16
+
17
+ require 'test_bench/output/output'
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: test_bench-output
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nathan Ladd
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: test_bench-session
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: test_bench-bootstrap
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email: nathanladd+github@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/test_bench/output.rb
48
+ - lib/test_bench/output/controls.rb
49
+ - lib/test_bench/output/controls/data.rb
50
+ - lib/test_bench/output/controls/detail.rb
51
+ - lib/test_bench/output/controls/device.rb
52
+ - lib/test_bench/output/controls/events.rb
53
+ - lib/test_bench/output/controls/output.rb
54
+ - lib/test_bench/output/controls/random.rb
55
+ - lib/test_bench/output/controls/result.rb
56
+ - lib/test_bench/output/controls/style.rb
57
+ - lib/test_bench/output/controls/styling.rb
58
+ - lib/test_bench/output/controls/text.rb
59
+ - lib/test_bench/output/device/null.rb
60
+ - lib/test_bench/output/device/substitute.rb
61
+ - lib/test_bench/output/digest.rb
62
+ - lib/test_bench/output/output.rb
63
+ - lib/test_bench/output/writer.rb
64
+ - lib/test_bench/output/writer/buffer.rb
65
+ - lib/test_bench/output/writer/buffer/console.rb
66
+ - lib/test_bench/output/writer/defaults.rb
67
+ - lib/test_bench/output/writer/style.rb
68
+ - lib/test_bench/output/writer/substitute.rb
69
+ homepage: https://github.com/test-bench/test-bench-output
70
+ licenses:
71
+ - MIT
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubygems_version: 3.3.23
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: ruby
92
+ test_files: []