vedeu 0.0.32 → 0.0.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vedeu/application.rb +2 -0
  3. data/lib/vedeu/launcher.rb +1 -1
  4. data/lib/vedeu/models/colour.rb +7 -7
  5. data/lib/vedeu/models/command.rb +2 -0
  6. data/lib/vedeu/models/composition.rb +2 -2
  7. data/lib/vedeu/models/interface.rb +15 -6
  8. data/lib/vedeu/models/line.rb +5 -3
  9. data/lib/vedeu/models/presentation.rb +3 -3
  10. data/lib/vedeu/models/stream.rb +6 -3
  11. data/lib/vedeu/models/style.rb +31 -0
  12. data/lib/vedeu/output/interface_renderer.rb +1 -3
  13. data/lib/vedeu/support/coordinate.rb +21 -7
  14. data/lib/vedeu/support/parsing/json_parser.rb +3 -3
  15. data/test/lib/vedeu/application_test.rb +0 -11
  16. data/test/lib/vedeu/launcher_test.rb +0 -8
  17. data/test/lib/vedeu/models/collection_test.rb +3 -3
  18. data/test/lib/vedeu/models/colour_test.rb +7 -2
  19. data/test/lib/vedeu/models/command_test.rb +0 -6
  20. data/test/lib/vedeu/models/composition_test.rb +127 -37
  21. data/test/lib/vedeu/models/interface_collection_test.rb +8 -9
  22. data/test/lib/vedeu/models/interface_test.rb +64 -18
  23. data/test/lib/vedeu/models/line_test.rb +3 -7
  24. data/test/lib/vedeu/models/presentation_test.rb +7 -5
  25. data/test/lib/vedeu/models/stream_test.rb +21 -11
  26. data/test/lib/vedeu/models/style_test.rb +86 -0
  27. data/test/lib/vedeu/output/interface_renderer_test.rb +32 -5
  28. data/test/lib/vedeu/output/output_test.rb +8 -1
  29. data/test/lib/vedeu/repository/command_repository_test.rb +14 -10
  30. data/test/lib/vedeu/repository/interface_repository_test.rb +9 -9
  31. data/test/lib/vedeu/support/coordinate_test.rb +72 -19
  32. data/test/lib/vedeu/support/menu_test.rb +16 -16
  33. data/test/lib/vedeu/support/parsing/hash_parser_test.rb +7 -7
  34. data/test/lib/vedeu/support/parsing/json_parser_test.rb +1 -1
  35. data/test/lib/vedeu/support/terminal_test.rb +0 -7
  36. data/test/lib/vedeu_test.rb +0 -5
  37. data/test/test_helper.rb +1 -0
  38. data/vedeu.gemspec +2 -3
  39. metadata +7 -25
  40. data/lib/vedeu/models/style_collection.rb +0 -19
  41. data/lib/vedeu/support/geometry.rb +0 -62
  42. data/test/lib/vedeu/models/style_collection_test.rb +0 -13
  43. data/test/lib/vedeu/support/geometry_test.rb +0 -107
@@ -9,17 +9,19 @@ module Vedeu
9
9
  describe Presentation do
10
10
  describe '#colour' do
11
11
  it 'returns a Colour instance' do
12
- TestPresentation.new({
12
+ presentation = TestPresentation.new({
13
13
  colour: { foreground: '#ff0000', background: '#333333' }
14
- }).colour.must_be_instance_of(Colour)
14
+ })
15
+ presentation.colour.must_be_instance_of(Colour)
15
16
  end
16
17
  end
17
18
 
18
19
  describe '#style' do
19
20
  it 'has a style attribute' do
20
- TestPresentation.new({
21
- style: ['bold', 'underline']
22
- }).style.must_equal("\e[1m\e[4m")
21
+ presentation = TestPresentation.new({
22
+ style: ['bold', 'underline']
23
+ })
24
+ presentation.style.must_equal(['bold', 'underline'])
23
25
  end
24
26
  end
25
27
  end
@@ -4,37 +4,47 @@ require_relative '../../../../lib/vedeu/models/stream'
4
4
  module Vedeu
5
5
  describe Stream do
6
6
  it 'has a colour attribute' do
7
- Stream.new({
7
+ stream = Stream.new({
8
8
  colour: { foreground: '#ff0000', background: '#000000' }
9
- }).colour.must_be_instance_of(Colour)
9
+ })
10
+ stream.colour.must_be_instance_of(Colour)
10
11
  end
11
12
 
12
13
  it 'has a text attribute' do
13
- Stream.new({ text: 'Some text' }).text.must_equal('Some text')
14
+ stream = Stream.new({ text: 'Some text' })
15
+ stream.text.must_equal('Some text')
14
16
  end
15
17
 
16
18
  it 'has a style attribute' do
17
- Stream.new({ style: 'normal' }).style
18
- .must_equal("\e[24m\e[21m\e[27m")
19
+ stream = Stream.new({ style: 'normal' })
20
+ stream.style.must_equal("\e[24m\e[21m\e[27m")
19
21
  end
20
22
 
21
23
  describe '#to_s' do
22
24
  it 'returns a String' do
23
- Stream.new({
24
- style: 'normal',
25
+ stream = Stream.new({
25
26
  colour: { foreground: '#ff0000', background: '#000000' },
27
+ style: 'normal',
26
28
  text: 'Some text'
27
- }).to_s.must_equal("\e[38;5;196m\e[48;5;16m\e[24m\e[21m\e[27mSome text")
29
+ })
30
+
31
+ stream.to_s.must_equal(
32
+ "\e[38;5;196m\e[48;5;16m" \
33
+ "\e[24m\e[21m\e[27m" \
34
+ "Some text"
35
+ )
28
36
  end
29
37
  end
30
38
 
31
39
  describe '#to_json' do
32
40
  it 'returns a String' do
33
- Stream.new({
34
- style: 'normal',
41
+ stream = Stream.new({
35
42
  colour: { foreground: '#ff0000', background: '#000000' },
43
+ style: 'normal',
36
44
  text: 'Some text'
37
- }).to_json.must_equal("{\"colour\":{\"foreground\":\"#ff0000\",\"background\":\"#000000\"},\"style\":\"\\u001b[24m\\u001b[21m\\u001b[27m\",\"text\":\"Some text\"}")
45
+ })
46
+
47
+ stream.to_json.must_equal("{\"colour\":{\"foreground\":\"#ff0000\",\"background\":\"#000000\"},\"style\":[\"normal\"],\"text\":\"Some text\"}")
38
48
  end
39
49
  end
40
50
  end
@@ -0,0 +1,86 @@
1
+ require_relative '../../../test_helper'
2
+ require_relative '../../../../lib/vedeu/models/presentation'
3
+ require_relative '../../../../lib/vedeu/models/style'
4
+
5
+ module Vedeu
6
+ class TestStyle
7
+ include Presentation
8
+ include Style
9
+ end
10
+
11
+ describe Style do
12
+ describe '#style' do
13
+ it 'returns an escape sequence for a single style' do
14
+ test_style = TestStyle.new(style: 'normal')
15
+ test_style.style.must_equal("\e[24m\e[21m\e[27m")
16
+ end
17
+
18
+ it 'returns an escape sequence for multiple styles' do
19
+ test_style = TestStyle.new(style: ['normal', 'underline'])
20
+ test_style.style.must_equal("\e[24m\e[21m\e[27m\e[4m")
21
+ end
22
+
23
+ it 'returns an empty string for an unknown style' do
24
+ test_style = TestStyle.new(style: 'unknown')
25
+ test_style.style.must_equal('')
26
+ end
27
+
28
+ it 'has a style attribute' do
29
+ test_style = TestStyle.new(style: ['normal'])
30
+ test_style.style.must_equal("\e[24m\e[21m\e[27m")
31
+ end
32
+
33
+ it 'returns an empty string for empty or nil' do
34
+ test_style = TestStyle.new(style: '')
35
+ test_style.style.must_equal('')
36
+ end
37
+
38
+ it 'returns an empty string for empty or nil' do
39
+ test_style = TestStyle.new(style: nil)
40
+ test_style.style.must_equal('')
41
+ end
42
+
43
+ it 'returns an empty string for empty or nil' do
44
+ test_style = TestStyle.new(style: [])
45
+ test_style.style.must_equal('')
46
+ end
47
+ end
48
+
49
+ describe '#style_original' do
50
+ it 'returns an escape sequence for a single style' do
51
+ test_style = TestStyle.new(style: 'normal')
52
+ test_style.style_original.must_equal(['normal'])
53
+ end
54
+
55
+ it 'returns an escape sequence for multiple styles' do
56
+ test_style = TestStyle.new(style: ['normal', 'underline'])
57
+ test_style.style_original.must_equal(['normal', 'underline'])
58
+ end
59
+
60
+ it 'returns an empty string for an unknown style' do
61
+ test_style = TestStyle.new(style: 'unknown')
62
+ test_style.style_original.must_equal(['unknown'])
63
+ end
64
+
65
+ it 'has a style attribute' do
66
+ test_style = TestStyle.new(style: ['normal'])
67
+ test_style.style_original.must_equal(['normal'])
68
+ end
69
+
70
+ it 'returns an empty string for empty or nil' do
71
+ test_style = TestStyle.new(style: '')
72
+ test_style.style_original.must_equal([''])
73
+ end
74
+
75
+ it 'returns an empty string for empty or nil' do
76
+ test_style = TestStyle.new(style: nil)
77
+ test_style.style_original.must_equal('')
78
+ end
79
+
80
+ it 'returns an empty string for empty or nil' do
81
+ test_style = TestStyle.new(style: [])
82
+ test_style.style_original.must_equal('')
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,24 +1,51 @@
1
1
  require_relative '../../../test_helper'
2
+ require_relative '../../../../lib/vedeu/repository/interface_repository'
2
3
  require_relative '../../../../lib/vedeu/output/interface_renderer'
3
4
  require_relative '../../../../lib/vedeu/models/interface'
4
5
 
5
6
  module Vedeu
6
7
  describe InterfaceRenderer do
8
+ before { InterfaceRepository.reset }
9
+
7
10
  describe '.clear' do
8
11
  it 'returns the escape sequence to clear the whole interface' do
9
- interface = Interface.new({ name: 'dummy', width: 20, height: 2 })
10
- InterfaceRenderer.clear(interface).must_equal("\e[1;1H \e[1;1H\e[2;1H \e[2;1H")
12
+ interface = Interface.new({
13
+ name: '.clear',
14
+ width: 5,
15
+ height: 2
16
+ })
17
+ InterfaceRenderer.clear(interface).must_equal(
18
+ "\e[1;1H \e[1;1H" \
19
+ "\e[2;1H \e[2;1H"
20
+ )
11
21
  end
12
22
 
13
23
  it 'returns the escape sequence to clear the whole interface with specified colours' do
14
- interface = Interface.new({ name: 'dummy', width: 20, height: 2, colour: { foreground: '#00ff00', background: '#ffff00' } })
15
- InterfaceRenderer.clear(interface).must_equal("\e[38;5;46m\e[48;5;226m\e[1;1H \e[1;1H\e[2;1H \e[2;1H")
24
+ interface = Interface.new({
25
+ name: '.clear',
26
+ width: 5,
27
+ height: 2,
28
+ colour: {
29
+ foreground: '#00ff00',
30
+ background: '#ffff00'
31
+ }
32
+ })
33
+ InterfaceRenderer.clear(interface).must_equal(
34
+ "\e[38;5;46m\e[48;5;226m" \
35
+ "\e[1;1H \e[1;1H" \
36
+ "\e[2;1H \e[2;1H"
37
+ )
16
38
  end
17
39
  end
18
40
 
19
41
  describe '.render' do
20
42
  it 'returns the content for the interface' do
21
- interface = Interface.new({ name: 'dummy', width: 20, height: 2, lines: 'InterfaceRenderer.render' })
43
+ interface = Interface.new({
44
+ name: '.render',
45
+ width: 5,
46
+ height: 2,
47
+ lines: 'InterfaceRenderer.render'
48
+ })
22
49
  InterfaceRenderer.render(interface).must_equal("\e[1;1HInterfaceRenderer.render")
23
50
  end
24
51
  end
@@ -1,11 +1,18 @@
1
1
  require_relative '../../../test_helper'
2
2
  require_relative '../../../../lib/vedeu/output/output'
3
+ require_relative '../../../../lib/vedeu/support/terminal'
3
4
 
4
5
  module Vedeu
5
6
  describe Output do
6
7
  describe '.render' do
7
8
  it 'returns an Array' do
8
- Output.render.must_be_instance_of(Array)
9
+ output = "\e[3;3H \e[3;3H" \
10
+ "\e[3;3HSome text...\e[3;3H"
11
+ InterfaceRepository.stub(:refresh, [output]) do
12
+ Terminal.stub(:output, output) do
13
+ Output.render.first.must_equal(output)
14
+ end
15
+ end
9
16
  end
10
17
  end
11
18
  end
@@ -22,20 +22,24 @@ module Vedeu
22
22
 
23
23
  describe '.by_input' do
24
24
  it 'returns the correct command when the command was found by keypress' do
25
- CommandRepository.by_input('b').name.must_equal('banana')
26
- CommandRepository.by_input('b').name.wont_equal('apple')
27
- CommandRepository.by_input('b').keypress.must_equal('b')
25
+ command = CommandRepository.by_input('b')
26
+
27
+ command.name.must_equal('banana')
28
+ command.name.wont_equal('apple')
29
+ command.keypress.must_equal('b')
28
30
  end
29
31
 
30
32
  it 'returns the correct command when the command was found by keyword' do
31
- CommandRepository.by_input('apple').keypress.must_equal('a')
32
- CommandRepository.by_input('apple').keypress.wont_equal('b')
33
- CommandRepository.by_input('apple').name.wont_equal('banana')
33
+ command = CommandRepository.by_input('apple')
34
+
35
+ command.keypress.must_equal('a')
36
+ command.keypress.wont_equal('b')
37
+ command.name.wont_equal('banana')
34
38
  end
35
39
 
36
40
  it 'returns FalseClass when no command was found' do
37
- CommandRepository.by_input('not_found')
38
- .must_be_instance_of(FalseClass)
41
+ command = CommandRepository.by_input('not_found')
42
+ command.must_be_instance_of(FalseClass)
39
43
  end
40
44
 
41
45
  it 'returns FalseClass when there is no input' do
@@ -45,8 +49,8 @@ module Vedeu
45
49
 
46
50
  describe '.create' do
47
51
  it 'returns a Command' do
48
- skip
49
- CommandRepository.create({}).must_be_instance_of(Command)
52
+ command = CommandRepository.create({})
53
+ command.must_be_instance_of(Command)
50
54
  end
51
55
  end
52
56
 
@@ -6,9 +6,9 @@ module Vedeu
6
6
  describe '.create' do
7
7
  it 'returns an Interface' do
8
8
  InterfaceRepository.create({
9
- name: 'dummy',
10
- width: 15,
11
- height: 2
9
+ name: 'dummy',
10
+ width: 5,
11
+ height: 5
12
12
  }).must_be_instance_of(Interface)
13
13
  end
14
14
  end
@@ -16,9 +16,9 @@ module Vedeu
16
16
  describe '.find' do
17
17
  it 'returns an Interface when the interface exists' do
18
18
  InterfaceRepository.create({
19
- name: 'dummy',
20
- width: 15,
21
- height: 2
19
+ name: 'dummy',
20
+ width: 5,
21
+ height: 5
22
22
  })
23
23
  InterfaceRepository.find('dummy')
24
24
  .must_be_instance_of(Interface)
@@ -57,13 +57,13 @@ module Vedeu
57
57
  it 'returns the collection in order they should be drawn' do
58
58
  InterfaceRepository.reset
59
59
  InterfaceRepository.create({
60
- name: 'a', width: 15, height: 2, z: 2
60
+ name: 'a', width: 5, height: 5, z: 2
61
61
  }).enqueue("a")
62
62
  InterfaceRepository.create({
63
- name: 'b', width: 15, height: 2, z: 1
63
+ name: 'b', width: 5, height: 5, z: 1
64
64
  }).enqueue("b")
65
65
  InterfaceRepository.create({
66
- name: 'c', width: 15, height: 2, z: 3
66
+ name: 'c', width: 5, height: 5, z: 3
67
67
  }).enqueue("c")
68
68
  InterfaceRepository.refresh.must_equal(['b', 'a', 'c'])
69
69
  end
@@ -11,6 +11,38 @@ module Vedeu
11
11
  proc { Coordinate.new({ height: 6 }) }.must_raise(KeyError)
12
12
  end
13
13
 
14
+ describe '#origin' do
15
+ it 'returns the origin for the interface' do
16
+ coordinate = Coordinate.new({ width: 5, height: 5, centred: false })
17
+ coordinate.origin.must_equal("\e[1;1H")
18
+ end
19
+
20
+ it 'returns the origin for the interface' do
21
+ console = IO.console
22
+ console.stub :winsize, [25, 80] do
23
+ coordinate = Coordinate.new({ width: 5, height: 5 })
24
+ coordinate.origin.must_equal("\e[10;38H")
25
+ end
26
+ end
27
+
28
+ it 'returns the line position relative to the origin' do
29
+ coordinate = Coordinate.new({ width: 5, height: 5, centred: false })
30
+ coordinate.origin(3).must_equal("\e[4;1H")
31
+ end
32
+
33
+ it 'returns the origin for the interface when the interface' \
34
+ ' is at a custom position' do
35
+ coordinate = Coordinate.new({ width: 5, height: 5, x: 3, y: 6, centred: false })
36
+ coordinate.origin.must_equal("\e[6;3H")
37
+ end
38
+
39
+ it 'returns the line position relative to the origin when the' \
40
+ ' interface is at a custom position' do
41
+ coordinate = Coordinate.new({ width: 5, height: 5, x: 3, y: 6, centred: false })
42
+ coordinate.origin(3).must_equal("\e[9;3H")
43
+ end
44
+ end
45
+
14
46
  describe '#terminal_height' do
15
47
  it 'raises an exception if the value is less than 1' do
16
48
  coordinate = Coordinate.new({ height: 6, width: 18, terminal_height: -2 })
@@ -28,16 +60,16 @@ module Vedeu
28
60
  it 'returns the value of terminal_height' do
29
61
  console = IO.console
30
62
  console.stub :winsize, [25, 80] do
31
- Coordinate.new({ height: 6, width: 18, terminal_height: 20 })
32
- .terminal_height.must_equal(20)
63
+ coordinate = Coordinate.new({ height: 6, width: 18, terminal_height: 20 })
64
+ coordinate.terminal_height.must_equal(20)
33
65
  end
34
66
  end
35
67
 
36
68
  it 'returns the default height if not set' do
37
69
  console = IO.console
38
70
  console.stub :winsize, [25, 80] do
39
- Coordinate.new({ height: 6, width: 18 })
40
- .instance_variable_get('@terminal_height').must_equal(25)
71
+ coordinate = Coordinate.new({ height: 6, width: 18 })
72
+ coordinate.terminal_height.must_equal(25)
41
73
  end
42
74
  end
43
75
  end
@@ -56,8 +88,17 @@ module Vedeu
56
88
  end
57
89
  end
58
90
 
91
+ # it 'raises an exception if the value combined with y position will cause content wrapping' do
92
+ # console = IO.console
93
+ # console.stub :winsize, [25, 80] do
94
+ # coordinate = Coordinate.new({ height: 20, width: 18, y: 10 })
95
+ # proc { coordinate.height }.must_raise(OutOfBoundsError)
96
+ # end
97
+ # end
98
+
59
99
  it 'returns the value of height' do
60
- Coordinate.new({ height: 6, width: 18 }).height.must_equal(6)
100
+ coordinate = Coordinate.new({ height: 6, width: 18 })
101
+ coordinate.height.must_equal(6)
61
102
  end
62
103
  end
63
104
 
@@ -76,11 +117,13 @@ module Vedeu
76
117
  end
77
118
 
78
119
  it 'returns the value of y' do
79
- Coordinate.new({ height: 6, width: 18, y: 6 }).y.must_equal(6)
120
+ coordinate = Coordinate.new({ height: 6, width: 18, y: 6 })
121
+ coordinate.y.must_equal(6)
80
122
  end
81
123
 
82
124
  it 'returns 1 if not set' do
83
- Coordinate.new({ height: 6, width: 18 }).y.must_equal(1)
125
+ coordinate = Coordinate.new({ height: 6, width: 18 })
126
+ coordinate.y.must_equal(1)
84
127
  end
85
128
  end
86
129
 
@@ -101,16 +144,16 @@ module Vedeu
101
144
  it 'returns the value of terminal_width' do
102
145
  console = IO.console
103
146
  console.stub :winsize, [25, 80] do
104
- Coordinate.new({ height: 6, width: 18, terminal_width: 40 })
105
- .terminal_width.must_equal(40)
147
+ coordinate = Coordinate.new({ height: 6, width: 18, terminal_width: 40 })
148
+ coordinate.terminal_width.must_equal(40)
106
149
  end
107
150
  end
108
151
 
109
152
  it 'returns the default width if not set' do
110
153
  console = IO.console
111
154
  console.stub :winsize, [25, 80] do
112
- Coordinate.new({ height: 6, width: 18 })
113
- .terminal_width.must_equal(80)
155
+ coordinate = Coordinate.new({ height: 6, width: 18 })
156
+ coordinate.terminal_width.must_equal(80)
114
157
  end
115
158
  end
116
159
  end
@@ -129,9 +172,17 @@ module Vedeu
129
172
  end
130
173
  end
131
174
 
175
+ # it 'raises an exception if the value combined with x position will cause content wrapping' do
176
+ # console = IO.console
177
+ # console.stub :winsize, [25, 80] do
178
+ # coordinate = Coordinate.new({ height: 20, width: 75, x: 10 })
179
+ # proc { coordinate.width }.must_raise(OutOfBoundsError)
180
+ # end
181
+ # end
182
+
132
183
  it 'returns the value of width' do
133
- Coordinate.new({ height: 6, width: 18, x: 6 }).width
134
- .must_equal(18)
184
+ coordinate = Coordinate.new({ height: 6, width: 18, x: 6 })
185
+ coordinate.width.must_equal(18)
135
186
  end
136
187
  end
137
188
 
@@ -150,23 +201,25 @@ module Vedeu
150
201
  end
151
202
 
152
203
  it 'returns the value of x' do
153
- Coordinate.new({ height: 6, width: 18, x: 6 }).x.must_equal(6)
204
+ coordinate = Coordinate.new({ height: 6, width: 18, x: 6 })
205
+ coordinate.x.must_equal(6)
154
206
  end
155
207
 
156
208
  it 'returns 1 if not set' do
157
- Coordinate.new({ height: 6, width: 18 }).x.must_equal(1)
209
+ coordinate = Coordinate.new({ height: 6, width: 18 })
210
+ coordinate.x.must_equal(1)
158
211
  end
159
212
  end
160
213
 
161
214
  describe '#centered' do
162
215
  it 'has a centred attribute' do
163
- Coordinate.new({ height: 6, width: 18, centred: false })
164
- .centred.must_equal(false)
216
+ coordinate = Coordinate.new({ height: 6, width: 18, centred: false })
217
+ coordinate.centred.must_equal(false)
165
218
  end
166
219
 
167
220
  it 'sets the centred attribute to true if not set' do
168
- Coordinate.new({ height: 6, width: 18 })
169
- .centred.must_equal(true)
221
+ coordinate = Coordinate.new({ height: 6, width: 18 })
222
+ coordinate.centred.must_equal(true)
170
223
  end
171
224
  end
172
225