vedeu 0.1.12 → 0.1.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -0
  3. data/lib/vedeu.rb +12 -12
  4. data/lib/vedeu/api/api.rb +23 -18
  5. data/lib/vedeu/api/events.rb +1 -1
  6. data/lib/vedeu/api/interface.rb +29 -19
  7. data/lib/vedeu/api/line.rb +1 -34
  8. data/lib/vedeu/api/stream.rb +1 -34
  9. data/lib/vedeu/models/attributes/attributes.rb +7 -7
  10. data/lib/vedeu/models/attributes/colour_translator.rb +45 -7
  11. data/lib/vedeu/models/colour.rb +4 -2
  12. data/lib/vedeu/models/composition.rb +9 -9
  13. data/lib/vedeu/models/interface.rb +1 -1
  14. data/lib/vedeu/models/line.rb +17 -3
  15. data/lib/vedeu/{api → models}/store.rb +0 -2
  16. data/lib/vedeu/models/stream.rb +17 -3
  17. data/lib/vedeu/output/buffers.rb +14 -8
  18. data/lib/vedeu/output/view.rb +7 -3
  19. data/lib/vedeu/support/esc.rb +1 -14
  20. data/lib/vedeu/support/position.rb +31 -0
  21. data/lib/vedeu/support/terminal.rb +4 -0
  22. data/test/lib/vedeu/api/api_test.rb +21 -0
  23. data/test/lib/vedeu/api/interface_test.rb +765 -51
  24. data/test/lib/vedeu/configuration_test.rb +5 -0
  25. data/test/lib/vedeu/models/composition_test.rb +1 -1
  26. data/test/lib/vedeu/models/interface_test.rb +59 -17
  27. data/test/lib/vedeu/{api → models}/store_test.rb +12 -3
  28. data/test/lib/vedeu/output/clear_test.rb +1 -1
  29. data/test/lib/vedeu/output/render_test.rb +1 -1
  30. data/test/lib/vedeu/output/view_test.rb +17 -0
  31. data/test/lib/vedeu/support/esc_test.rb +0 -10
  32. data/test/lib/vedeu/support/position_test.rb +19 -0
  33. data/test/support/colour_test.sh +100 -0
  34. data/test/{stats.sh → support/stats.sh} +0 -0
  35. data/vedeu.gemspec +1 -1
  36. metadata +16 -10
  37. data/lib/vedeu/api/view.rb +0 -45
  38. data/test/lib/vedeu/api/view_test.rb +0 -565
@@ -9,11 +9,13 @@ module Vedeu
9
9
  end
10
10
 
11
11
  def foreground
12
- @foreground ||= ColourTranslator.new(attributes[:foreground]).foreground
12
+ @foreground ||= ColourTranslator
13
+ .new(attributes[:foreground], { truecolor: false }).foreground
13
14
  end
14
15
 
15
16
  def background
16
- @background ||= ColourTranslator.new(attributes[:background]).background
17
+ @background ||= ColourTranslator
18
+ .new(attributes[:background], { truecolor: false }).background
17
19
  end
18
20
 
19
21
  def to_s
@@ -5,18 +5,22 @@ module Vedeu
5
5
  end
6
6
 
7
7
  def attributes
8
- defaults.merge!(@attributes)
8
+ @_attributes ||= defaults.merge!(@attributes)
9
9
  end
10
10
 
11
11
  def interfaces
12
- @interfaces ||= if _interfaces.nil? || _interfaces.empty?
12
+ @interfaces ||= if attributes[:interfaces].nil? || attributes[:interfaces].empty?
13
13
  []
14
14
 
15
15
  else
16
- [_interfaces].flatten.map do |new_attributes|
17
- stored_attributes = API::Store.query(new_attributes[:name])
16
+ [ attributes[:interfaces] ].flatten.map do |attrs|
17
+ stored = Store.query(attrs[:name])
18
18
 
19
- Interface.new(stored_attributes.merge!(new_attributes))
19
+ combined = stored.merge(attrs) do |key, s, a|
20
+ key == :lines && s.empty? ? a : s
21
+ end
22
+
23
+ Interface.new(combined)
20
24
  end
21
25
 
22
26
  end
@@ -28,10 +32,6 @@ module Vedeu
28
32
 
29
33
  private
30
34
 
31
- def _interfaces
32
- attributes[:interfaces]
33
- end
34
-
35
35
  def defaults
36
36
  {
37
37
  interfaces: []
@@ -11,7 +11,7 @@ module Vedeu
11
11
  end
12
12
 
13
13
  def attributes
14
- defaults.merge!(@attributes)
14
+ @_attributes ||= defaults.merge!(@attributes)
15
15
  end
16
16
 
17
17
  def name
@@ -1,11 +1,21 @@
1
1
  module Vedeu
2
2
  class Line
3
- def initialize(attributes = {})
3
+ def self.build(attributes = {}, &block)
4
+ new(attributes, &block).attributes
5
+ end
6
+
7
+ def initialize(attributes = {}, &block)
4
8
  @attributes = attributes
9
+
10
+ if block_given?
11
+ @self_before_instance_eval = eval('self', block.binding)
12
+
13
+ instance_eval(&block)
14
+ end
5
15
  end
6
16
 
7
17
  def attributes
8
- defaults.merge!(@attributes)
18
+ @_attributes ||= defaults.merge!(@attributes)
9
19
  end
10
20
 
11
21
  def colour
@@ -30,8 +40,12 @@ module Vedeu
30
40
  {
31
41
  colour: {},
32
42
  streams: [],
33
- style: ''
43
+ style: []
34
44
  }
35
45
  end
46
+
47
+ def method_missing(method, *args, &block)
48
+ @self_before_instance_eval.send(method, *args, &block)
49
+ end
36
50
  end
37
51
  end
@@ -1,7 +1,6 @@
1
1
  module Vedeu
2
2
  EntityNotFound = Class.new(StandardError)
3
3
 
4
- module API
5
4
  module Store
6
5
  extend self
7
6
 
@@ -23,5 +22,4 @@ module Vedeu
23
22
  @storage ||= {}
24
23
  end
25
24
  end
26
- end
27
25
  end
@@ -1,11 +1,21 @@
1
1
  module Vedeu
2
2
  class Stream
3
- def initialize(attributes = {})
3
+ def self.build(attributes = {}, &block)
4
+ new(attributes, &block).attributes
5
+ end
6
+
7
+ def initialize(attributes = {}, &block)
4
8
  @attributes = attributes
9
+
10
+ if block_given?
11
+ @self_before_instance_eval = eval('self', block.binding)
12
+
13
+ instance_eval(&block)
14
+ end
5
15
  end
6
16
 
7
17
  def attributes
8
- defaults.merge!(@attributes)
18
+ @_attributes ||= defaults.merge!(@attributes)
9
19
  end
10
20
 
11
21
  def colour
@@ -53,11 +63,15 @@ module Vedeu
53
63
  def defaults
54
64
  {
55
65
  colour: {},
56
- style: '',
66
+ style: [],
57
67
  text: '',
58
68
  width: nil,
59
69
  align: :left
60
70
  }
61
71
  end
72
+
73
+ def method_missing(method, *args, &block)
74
+ @self_before_instance_eval.send(method, *args, &block)
75
+ end
62
76
  end
63
77
  end
@@ -6,17 +6,17 @@ module Vedeu
6
6
 
7
7
  def create(interface)
8
8
  buffers[interface.name][:clear] = Clear.call(interface)
9
+ buffers[interface.name][:group] = interface.group
9
10
 
10
- Vedeu.events.event("_refresh_#{interface.name}_".to_sym, interface.delay) do
11
+ Vedeu.event("_refresh_#{interface.name}_".to_sym, interface.delay) do
11
12
  refresh(interface.name)
12
13
  end
13
14
 
14
- # TODO: cannot refresh group since no logic to fetch group from buffer
15
- # unless interface.group.nil? || interface.group.empty?
16
- # Vedeu.events.event("_refresh_#{interface.group}_".to_sym, interface.delay) do
17
- # refresh_group(interface.group)
18
- # end
19
- # end
15
+ unless interface.group.nil? || interface.group.empty?
16
+ Vedeu.event("_refresh_group_#{interface.group}_".to_sym, interface.delay) do
17
+ refresh_group(interface.group)
18
+ end
19
+ end
20
20
  end
21
21
 
22
22
  def enqueue(name, sequence)
@@ -29,6 +29,12 @@ module Vedeu
29
29
  end
30
30
  end
31
31
 
32
+ def refresh_group(group)
33
+ buffers.select.map do |name, buffer|
34
+ name if buffer[:group] == group
35
+ end.compact.map { |name| refresh(name) }
36
+ end
37
+
32
38
  def refresh(name)
33
39
  data = query(name)
34
40
 
@@ -57,7 +63,7 @@ module Vedeu
57
63
 
58
64
  def buffers
59
65
  @buffers ||= Hash.new do |hash, key|
60
- hash[key] = { current: '', next: [], clear: '' }
66
+ hash[key] = { current: '', next: [], clear: '', group: '' }
61
67
  end
62
68
  end
63
69
  end
@@ -13,7 +13,7 @@ module Vedeu
13
13
  end
14
14
 
15
15
  def render
16
- composition.interfaces.map do |interface|
16
+ interfaces.map do |interface|
17
17
  Buffers.enqueue(interface.name, interface.to_s)
18
18
  end
19
19
  end
@@ -26,11 +26,15 @@ module Vedeu
26
26
 
27
27
  attr_reader :object
28
28
 
29
+ def interfaces
30
+ composition.interfaces
31
+ end
32
+
29
33
  def composition
30
- @_composition ||= Composition.new(interfaces)
34
+ @_composition ||= Composition.new(attributes)
31
35
  end
32
36
 
33
- def interfaces
37
+ def attributes
34
38
  {
35
39
  interfaces: [ output ]
36
40
  }
@@ -3,20 +3,7 @@ module Vedeu
3
3
  extend self
4
4
 
5
5
  def set_position(y = 1, x = 1, &block)
6
- row = (y == 0 || y == nil) ? 1 : y
7
- column = (x == 0 || x == nil) ? 1 : x
8
-
9
- if block_given?
10
- out = []
11
- out << ["\e[", row, ';', column, 'H'].join
12
- out << yield
13
- out << ["\e[", row, ';', column, 'H'].join
14
- out
15
-
16
- else
17
- ["\e[", row, ';', column, 'H'].join
18
-
19
- end
6
+ Position.new(y, x).to_s(&block)
20
7
  end
21
8
 
22
9
  def string(value = '')
@@ -0,0 +1,31 @@
1
+ module Vedeu
2
+ class Position
3
+ def initialize(y = 1, x = 1)
4
+ @y, @x = y, x
5
+ end
6
+
7
+ def to_s(&block)
8
+ if block_given?
9
+ [ sequence, yield, sequence ].join
10
+
11
+ else
12
+ sequence
13
+
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def sequence
20
+ ["\e[", y, ';', x, 'H'].join
21
+ end
22
+
23
+ def y
24
+ (@y == 0 || @y == nil) ? 1 : @y
25
+ end
26
+
27
+ def x
28
+ (@x == 0 || @x == nil) ? 1 : @x
29
+ end
30
+ end
31
+ end
@@ -45,6 +45,10 @@ module Vedeu
45
45
  yield
46
46
  end
47
47
 
48
+ def clear_screen
49
+ output Esc.string 'clear'
50
+ end
51
+
48
52
  def restore_screen
49
53
  output Esc.string 'screen_exit'
50
54
  output clear_last_line
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ module Vedeu
4
+ describe API do
5
+ describe '.height' do
6
+ it 'returns the terminal height' do
7
+ IO.console.stub(:winsize, [24, 40]) do
8
+ Vedeu.height.must_equal(24)
9
+ end
10
+ end
11
+ end
12
+
13
+ describe '.width' do
14
+ it 'returns the terminal width' do
15
+ IO.console.stub(:winsize, [24, 40]) do
16
+ Vedeu.width.must_equal(40)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -3,70 +3,784 @@ require 'test_helper'
3
3
  module Vedeu
4
4
  module API
5
5
  describe Interface do
6
- before { API::Store.reset }
6
+ describe '#define' do
7
+ before { Vedeu::Store.reset }
7
8
 
8
- interface = Interface.new('widget')
9
+ interface = Interface.new({ name: 'widget' })
9
10
 
10
- it 'creates and stores a new interface' do
11
- interface.create.must_be_instance_of(Vedeu::Interface)
12
- end
11
+ it 'creates and stores a new interface' do
12
+ interface.define.must_be_instance_of(Vedeu::Interface)
13
+ end
14
+
15
+ it 'allows interfaces to share behaviour' do
16
+ IO.console.stub :winsize, [10, 40] do
17
+ main = Vedeu.interface('main') do
18
+ colour foreground: '#ff0000', background: '#000000'
19
+ cursor false
20
+ centred true
21
+ width 10
22
+ height 2
23
+ group 'example_group'
24
+ delay 0.25
25
+ end
26
+ status = Vedeu.interface('status') do
27
+ colour foreground: 'aadd00', background: '#4040cc'
28
+ cursor true
29
+ centred true
30
+ width 10
31
+ height 1
32
+ y use('main').bottom
33
+ x use('main').left
34
+ group 'example_group'
35
+ delay 0.25
36
+ end
13
37
 
14
- it 'allows interfaces to share behaviour' do
15
- IO.console.stub :winsize, [10, 40] do
16
- main = Vedeu.interface('main') do
17
- colour foreground: '#ff0000', background: '#000000'
18
- cursor false
19
- centred true
20
- width 10
21
- height 2
22
- end
23
- status = Vedeu.interface('status') do
24
- colour foreground: 'aadd00', background: '#4040cc'
25
- cursor true
26
- centred true
27
- width 10
28
- height 1
29
- y use('main').bottom
30
- x use('main').left
31
- end
32
-
33
- main.left.must_equal(15)
34
- main.top.must_equal(4)
35
- status.left.must_equal(15)
36
- status.top.must_equal(5)
38
+ main.left.must_equal(15)
39
+ main.top.must_equal(4)
40
+ status.left.must_equal(15)
41
+ status.top.must_equal(5)
42
+ end
37
43
  end
38
- end
39
44
 
40
- it 'raises an exception when the value is out of bounds' do
41
- proc { interface.create { x 0 } }.must_raise(XOutOfBounds)
42
- end
45
+ it 'raises an exception when the value is out of bounds' do
46
+ proc { interface.define { x 0 } }.must_raise(XOutOfBounds)
47
+ end
43
48
 
44
- it 'raises an exception when the value is out of bounds' do
45
- proc { interface.create { x 999 } }.must_raise(XOutOfBounds)
46
- end
49
+ it 'raises an exception when the value is out of bounds' do
50
+ proc { interface.define { x 999 } }.must_raise(XOutOfBounds)
51
+ end
47
52
 
48
- it 'raises an exception when the value is out of bounds' do
49
- proc { interface.create { y 0 } }.must_raise(YOutOfBounds)
50
- end
53
+ it 'raises an exception when the value is out of bounds' do
54
+ proc { interface.define { y 0 } }.must_raise(YOutOfBounds)
55
+ end
51
56
 
52
- it 'raises an exception when the value is out of bounds' do
53
- proc { interface.create { y 999 } }.must_raise(YOutOfBounds)
54
- end
57
+ it 'raises an exception when the value is out of bounds' do
58
+ proc { interface.define { y 999 } }.must_raise(YOutOfBounds)
59
+ end
55
60
 
56
- it 'raises an exception when the value is out of bounds' do
57
- proc { interface.create { width 0 } }.must_raise(InvalidWidth)
58
- end
61
+ it 'raises an exception when the value is out of bounds' do
62
+ proc { interface.define { width 0 } }.must_raise(InvalidWidth)
63
+ end
59
64
 
60
- it 'raises an exception when the value is out of bounds' do
61
- proc { interface.create { width 999 } }.must_raise(InvalidWidth)
62
- end
65
+ it 'raises an exception when the value is out of bounds' do
66
+ proc { interface.define { width 999 } }.must_raise(InvalidWidth)
67
+ end
63
68
 
64
- it 'raises an exception when the value is out of bounds' do
65
- proc { interface.create { height 0 } }.must_raise(InvalidHeight)
69
+ it 'raises an exception when the value is out of bounds' do
70
+ proc { interface.define { height 0 } }.must_raise(InvalidHeight)
71
+ end
72
+
73
+ it 'raises an exception when the value is out of bounds' do
74
+ proc { interface.define { height 999 } }.must_raise(InvalidHeight)
75
+ end
66
76
  end
67
77
 
68
- it 'raises an exception when the value is out of bounds' do
69
- proc { interface.create { height 999 } }.must_raise(InvalidHeight)
78
+ describe '#build' do
79
+ before do
80
+ Vedeu::Store.reset
81
+ Vedeu.interface('testing_view') do
82
+ x 1
83
+ y 1
84
+ colour foreground: '#ffffff', background: '#000000'
85
+ centred false
86
+ end
87
+ end
88
+
89
+ it 'builds a basic view' do
90
+ Vedeu.view 'testing_view' do
91
+ line do
92
+ text '1. A line of text.'
93
+ text '2. Another line of text.'
94
+ end
95
+ end.must_equal(
96
+ {
97
+ name: 'testing_view',
98
+ group: '',
99
+ colour: {},
100
+ style: '',
101
+ geometry: {},
102
+ cursor: true,
103
+ delay: 0.0,
104
+ lines: [
105
+ {
106
+ colour: {},
107
+ style: [],
108
+ streams: [
109
+ {
110
+ text: '1. A line of text.',
111
+ }, {
112
+ text: '2. Another line of text.',
113
+ }
114
+ ]
115
+ }
116
+ ]
117
+ }
118
+ )
119
+ end
120
+
121
+ it 'handles coloured lines' do
122
+ Vedeu.view 'testing_view' do
123
+ line do
124
+ text '1. Line without colours.'
125
+ end
126
+ end.must_equal(
127
+ {
128
+ name: 'testing_view',
129
+ group: '',
130
+ colour: {},
131
+ style: '',
132
+ geometry: {},
133
+ cursor: true,
134
+ delay: 0.0,
135
+ lines: [
136
+ {
137
+ colour: {},
138
+ style: [],
139
+ streams: [{ text: '1. Line without colours.' }]
140
+ }
141
+ ]
142
+ }
143
+ )
144
+ end
145
+
146
+ it 'handles coloured lines' do
147
+ Vedeu.view 'testing_view' do
148
+ line do
149
+ colour background: '#ff0000', foreground: '#ffff00'
150
+ text '2. Line with colours.'
151
+ end
152
+ end.must_equal(
153
+ {
154
+ name: 'testing_view',
155
+ group: '',
156
+ colour: {},
157
+ style: '',
158
+ geometry: {},
159
+ cursor: true,
160
+ delay: 0.0,
161
+ lines: [
162
+ {
163
+ colour: { background: '#ff0000', foreground: '#ffff00' },
164
+ style: [],
165
+ streams: [{ text: '2. Line with colours.' }]
166
+ }
167
+ ]
168
+ }
169
+ )
170
+ end
171
+
172
+ it 'handles coloured lines' do
173
+ Vedeu.view 'testing_view' do
174
+ line do
175
+ colour foreground: '#a7ff00', background: '#005700'
176
+ text '3. Line with explicit colour declaration.'
177
+ end
178
+ end.must_equal(
179
+ {
180
+ name: 'testing_view',
181
+ group: '',
182
+ colour: {},
183
+ style: '',
184
+ geometry: {},
185
+ cursor: true,
186
+ delay: 0.0,
187
+ lines: [
188
+ {
189
+ colour: { background: '#005700', foreground: '#a7ff00' },
190
+ style: [],
191
+ streams: [{ text: '3. Line with explicit colour declaration.' }]
192
+ }
193
+ ]
194
+ }
195
+ )
196
+ end
197
+
198
+ it 'handles coloured lines' do
199
+ Vedeu.view 'testing_view' do
200
+ line do # actually uses streams
201
+ foreground '#ff00ff' do
202
+ text '4. Line with only foreground set.'
203
+ end
204
+ end
205
+ end.must_equal(
206
+ {
207
+ name: 'testing_view',
208
+ group: '',
209
+ colour: {},
210
+ style: '',
211
+ geometry: {},
212
+ cursor: true,
213
+ delay: 0.0,
214
+ lines: [
215
+ {
216
+ colour: {},
217
+ style: [],
218
+ streams: [{
219
+ colour: { foreground: '#ff00ff' },
220
+ style: [],
221
+ text: '4. Line with only foreground set.',
222
+ width: nil,
223
+ align: :left
224
+ }]
225
+ }
226
+ ]
227
+ }
228
+ )
229
+ end
230
+
231
+ it 'handles coloured lines' do
232
+ Vedeu.view 'testing_view' do
233
+ line do # actually uses streams
234
+ background '#00ff00' do
235
+ text '5. Line with only background set.'
236
+ end
237
+ end
238
+ end.must_equal(
239
+ {
240
+ name: 'testing_view',
241
+ group: '',
242
+ colour: {},
243
+ style: '',
244
+ geometry: {},
245
+ cursor: true,
246
+ delay: 0.0,
247
+ lines: [
248
+ {
249
+ colour: {},
250
+ style: [],
251
+ streams: [{
252
+ colour: { background: '#00ff00' },
253
+ style: [],
254
+ text: '5. Line with only background set.',
255
+ width: nil,
256
+ align: :left
257
+ }]
258
+ }
259
+ ]
260
+ }
261
+ )
262
+ end
263
+
264
+ it 'handles styles' do
265
+ Vedeu.view 'testing_view' do
266
+ line do
267
+ style 'normal'
268
+ text '1. Line with a normal style.'
269
+ end
270
+ end.must_equal(
271
+ {
272
+ name: 'testing_view',
273
+ group: '',
274
+ colour: {},
275
+ style: '',
276
+ geometry: {},
277
+ cursor: true,
278
+ delay: 0.0,
279
+ lines: [
280
+ {
281
+ colour: {},
282
+ style: ['normal'],
283
+ streams: [{
284
+ text: '1. Line with a normal style.'
285
+ }]
286
+ }
287
+ ]
288
+ }
289
+ )
290
+ end
291
+
292
+ it 'handles styles' do
293
+ Vedeu.view 'testing_view' do
294
+ line do
295
+ style 'underline'
296
+ text '2. Line with an underline style.'
297
+ end
298
+ end.must_equal(
299
+ {
300
+ name: 'testing_view',
301
+ group: '',
302
+ colour: {},
303
+ style: '',
304
+ geometry: {},
305
+ cursor: true,
306
+ delay: 0.0,
307
+ lines: [
308
+ {
309
+ colour: {},
310
+ style: ['underline'],
311
+ streams: [{
312
+ text: '2. Line with an underline style.'
313
+ }]
314
+ }
315
+ ]
316
+ }
317
+ )
318
+ end
319
+
320
+ it 'handles styles' do
321
+ Vedeu.view 'testing_view' do
322
+ line do # actually uses streams
323
+ style 'normal' do
324
+ text '3. Line with a normal style.'
325
+ end
326
+ end
327
+ end.must_equal(
328
+ {
329
+ name: 'testing_view',
330
+ group: '',
331
+ colour: {},
332
+ style: '',
333
+ geometry: {},
334
+ cursor: true,
335
+ delay: 0.0,
336
+ lines: [
337
+ {
338
+ colour: {},
339
+ style: [],
340
+ streams: [{
341
+ colour: {},
342
+ style: ['normal'],
343
+ text: '3. Line with a normal style.',
344
+ width: nil,
345
+ align: :left
346
+ }]
347
+ }
348
+ ]
349
+ }
350
+ )
351
+ end
352
+
353
+ it 'handles styles' do
354
+ Vedeu.view 'testing_view' do
355
+ line do # actually uses streams
356
+ style 'underline' do
357
+ text '4. Line with an underlined style.'
358
+ end
359
+ end
360
+ end.must_equal(
361
+ {
362
+ name: 'testing_view',
363
+ group: '',
364
+ colour: {},
365
+ style: '',
366
+ geometry: {},
367
+ cursor: true,
368
+ delay: 0.0,
369
+ lines: [
370
+ {
371
+ colour: {},
372
+ style: [],
373
+ streams: [{
374
+ colour: {},
375
+ style: ['underline'],
376
+ text: '4. Line with an underlined style.',
377
+ width: nil,
378
+ align: :left
379
+ }]
380
+ }
381
+ ]
382
+ }
383
+ )
384
+ end
385
+
386
+ it 'handles streams, which means sub-line colours and styles' do
387
+ Vedeu.view 'testing_view' do
388
+ line do
389
+ stream do
390
+ text 'A stream of text.'
391
+ end
392
+ end
393
+ end.must_equal(
394
+ {
395
+ name: 'testing_view',
396
+ group: '',
397
+ colour: {},
398
+ style: '',
399
+ geometry: {},
400
+ cursor: true,
401
+ delay: 0.0,
402
+ lines: [
403
+ {
404
+ colour: {},
405
+ style: [],
406
+ streams: [
407
+ {
408
+ colour: {},
409
+ style: [],
410
+ text: 'A stream of text.',
411
+ width: nil,
412
+ align: :left
413
+ }
414
+ ]
415
+ }
416
+ ]
417
+ }
418
+ )
419
+ end
420
+
421
+ it 'handles streams, which means sub-line colours and styles' do
422
+ Vedeu.view 'testing_view' do
423
+ line do
424
+ stream do # Stream is an 'explicit declaration'.
425
+ # We don't need it unless we want to add colours and styles.
426
+ # See below.
427
+ text '1. Two streams of text, these will be'
428
+ end
429
+
430
+ stream do
431
+ text ' on the same line- note the space.'
432
+ end
433
+ end
434
+ end.must_equal(
435
+ {
436
+ name: 'testing_view',
437
+ group: '',
438
+ colour: {},
439
+ style: '',
440
+ geometry: {},
441
+ cursor: true,
442
+ delay: 0.0,
443
+ lines: [
444
+ {
445
+ colour: {},
446
+ style: [],
447
+ streams: [
448
+ {
449
+ colour: {},
450
+ style: [],
451
+ text: '1. Two streams of text, these will be',
452
+ width: nil,
453
+ align: :left
454
+ }, {
455
+ colour: {},
456
+ style: [],
457
+ text: ' on the same line- note the space.',
458
+ width: nil,
459
+ align: :left
460
+ }
461
+ ]
462
+ }
463
+ ]
464
+ }
465
+ )
466
+ end
467
+
468
+ it 'handles streams, which means sub-line colours and styles' do
469
+ Vedeu.view 'testing_view' do
470
+ line do
471
+ stream do
472
+ text '2. Streams can have'
473
+ end
474
+
475
+ stream do
476
+ colour foreground: '#ff0000', background: '#00ff00'
477
+ text ' colours too.'
478
+ end
479
+ end
480
+ end.must_equal(
481
+ {
482
+ name: 'testing_view',
483
+ group: '',
484
+ colour: {},
485
+ style: '',
486
+ geometry: {},
487
+ cursor: true,
488
+ delay: 0.0,
489
+ lines: [
490
+ {
491
+ colour: {},
492
+ style: [],
493
+ streams: [
494
+ {
495
+ colour: {},
496
+ style: [],
497
+ text: '2. Streams can have',
498
+ width: nil,
499
+ align: :left
500
+ }, {
501
+ colour: {
502
+ foreground: '#ff0000',
503
+ background: '#00ff00'
504
+ },
505
+ style: [],
506
+ text: ' colours too.',
507
+ width: nil,
508
+ align: :left
509
+ }
510
+ ]
511
+ }
512
+ ]
513
+ }
514
+ )
515
+ end
516
+
517
+ it 'handles streams, which means sub-line colours and styles' do
518
+ Vedeu.view 'testing_view' do
519
+ line do
520
+ stream do
521
+ text '3. Streams can have'
522
+ end
523
+
524
+ stream do
525
+ style 'underline'
526
+ text ' styles too.'
527
+ end
528
+ end
529
+ end.must_equal(
530
+ {
531
+ name: 'testing_view',
532
+ group: '',
533
+ colour: {},
534
+ style: '',
535
+ geometry: {},
536
+ cursor: true,
537
+ delay: 0.0,
538
+ lines: [
539
+ {
540
+ colour: {},
541
+ style: [],
542
+ streams: [
543
+ {
544
+ colour: {},
545
+ style: [],
546
+ text: '3. Streams can have',
547
+ width: nil,
548
+ align: :left
549
+ }, {
550
+ colour: {},
551
+ style: ['underline'],
552
+ text: ' styles too.',
553
+ width: nil,
554
+ align: :left
555
+ }
556
+ ]
557
+ }
558
+ ]
559
+ }
560
+ )
561
+ end
562
+
563
+ it 'handles alignment' do
564
+ Vedeu.view 'testing_view' do
565
+ line do
566
+ stream do
567
+ width 80
568
+ text 'This is aligned left, and padded with spaces.'
569
+ end
570
+ end
571
+ end.must_equal(
572
+ {
573
+ name: 'testing_view',
574
+ group: '',
575
+ colour: {},
576
+ style: '',
577
+ geometry: {},
578
+ cursor: true,
579
+ delay: 0.0,
580
+ lines: [{
581
+ colour: {},
582
+ style: [],
583
+ streams: [{
584
+ align: :left,
585
+ colour: {},
586
+ style: [],
587
+ width: 80,
588
+ text: 'This is aligned left, and padded with spaces.'
589
+ }]
590
+ }]
591
+ }
592
+ )
593
+ end
594
+
595
+ it 'handles alignment' do
596
+ Vedeu.view 'testing_view' do
597
+ line do
598
+ stream do
599
+ width 80
600
+ align :left # explicit
601
+ text 'This is aligned left, and padded with spaces.'
602
+ end
603
+ end
604
+ end.must_equal(
605
+ {
606
+ name: 'testing_view',
607
+ group: '',
608
+ colour: {},
609
+ style: '',
610
+ geometry: {},
611
+ cursor: true,
612
+ delay: 0.0,
613
+ lines: [{
614
+ colour: {},
615
+ style: [],
616
+ streams: [{
617
+ colour: {},
618
+ style: [],
619
+ width: 80,
620
+ align: :left,
621
+ text: 'This is aligned left, and padded with spaces.'
622
+ }]
623
+ }]
624
+ }
625
+ )
626
+ end
627
+
628
+ it 'handles alignment' do
629
+ Vedeu.view 'testing_view' do
630
+ line do
631
+ stream do
632
+ width 80
633
+ align :centre
634
+ text 'This is aligned centrally, and padded with spaces.'
635
+ end
636
+ end
637
+ end.must_equal(
638
+ {
639
+ name: 'testing_view',
640
+ group: '',
641
+ colour: {},
642
+ style: '',
643
+ geometry: {},
644
+ cursor: true,
645
+ delay: 0.0,
646
+ lines: [{
647
+ colour: {},
648
+ style: [],
649
+ streams: [{
650
+ colour: {},
651
+ style: [],
652
+ width: 80,
653
+ align: :centre,
654
+ text: 'This is aligned centrally, and padded with spaces.'
655
+ }]
656
+ }]
657
+ }
658
+ )
659
+ end
660
+
661
+ it 'handles alignment' do
662
+ Vedeu.view 'testing_view' do
663
+ line do
664
+ stream do
665
+ width 80
666
+ align :right
667
+ text 'This is aligned right, and padded with spaces.'
668
+ end
669
+ end
670
+ end.must_equal(
671
+ {
672
+ name: 'testing_view',
673
+ group: '',
674
+ colour: {},
675
+ style: '',
676
+ geometry: {},
677
+ cursor: true,
678
+ delay: 0.0,
679
+ lines: [{
680
+ colour: {},
681
+ style: [],
682
+ streams: [{
683
+ colour: {},
684
+ style: [],
685
+ width: 80,
686
+ align: :right,
687
+ text: 'This is aligned right, and padded with spaces.'
688
+ }]
689
+ }]
690
+ }
691
+ )
692
+ end
693
+
694
+ it 'handles multiple colour and text statements correctly' do
695
+ Vedeu.view 'testing_view' do
696
+ line do
697
+ foreground('#ffff00') { text "\u{25B2}" }
698
+ text " Prev"
699
+
700
+ foreground('#ffff00') { text "\u{25BC}" }
701
+ text " Next"
702
+
703
+ foreground('#ffff00') { text "\u{21B2}" }
704
+ text " Select"
705
+
706
+ foreground('#ffff00') { text "\u{2395}" }
707
+ text " Pause"
708
+
709
+ foreground('#ffff00') { text "Q" }
710
+ text " Quit"
711
+ end
712
+ end.must_equal(
713
+ {
714
+ name: 'testing_view',
715
+ group: '',
716
+ colour: {},
717
+ style: '',
718
+ geometry: {},
719
+ cursor: true,
720
+ delay: 0.0,
721
+ lines: [
722
+ {
723
+ colour: {},
724
+ style: [],
725
+ streams: [
726
+ {
727
+ colour: {
728
+ foreground: "#ffff00"
729
+ },
730
+ style: [],
731
+ text: "▲",
732
+ width: nil,
733
+ align: :left
734
+ }, {
735
+ text: " Prev",
736
+ }, {
737
+ colour: {
738
+ foreground: "#ffff00"
739
+ },
740
+ style: [],
741
+ text: "▼",
742
+ width: nil,
743
+ align: :left
744
+ }, {
745
+ text: " Next",
746
+ }, {
747
+ colour: {
748
+ foreground: "#ffff00"
749
+ },
750
+ style: [],
751
+ text: "↲",
752
+ width: nil,
753
+ align: :left
754
+ }, {
755
+ text: " Select",
756
+ }, {
757
+ colour: {
758
+ foreground: "#ffff00"
759
+ },
760
+ style: [],
761
+ text: "⎕",
762
+ width: nil,
763
+ align: :left
764
+ }, {
765
+ text: " Pause",
766
+ }, {
767
+ colour: {
768
+ foreground: "#ffff00"
769
+ },
770
+ style: [],
771
+ text: "Q",
772
+ width: nil,
773
+ align: :left
774
+ }, {
775
+ text: " Quit",
776
+ }
777
+ ]
778
+ }
779
+ ]
780
+ }
781
+ )
782
+ end
783
+
70
784
  end
71
785
  end
72
786
  end