vedeu 0.2.10 → 0.2.11

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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/docs/events.md +6 -0
  3. data/examples/{cursor_app/cursor_app.rb → cursor_app.rb} +1 -1
  4. data/examples/{lines_app/lines_app.rb → lines_app.rb} +1 -1
  5. data/lib/vedeu.rb +48 -28
  6. data/lib/vedeu/api/api.rb +8 -95
  7. data/lib/vedeu/application.rb +6 -2
  8. data/lib/vedeu/{models → colours}/background.rb +1 -1
  9. data/lib/vedeu/{models → colours}/colour.rb +0 -0
  10. data/lib/vedeu/{models → colours}/foreground.rb +2 -2
  11. data/lib/vedeu/{support/colour_translator.rb → colours/translator.rb} +7 -7
  12. data/lib/vedeu/input/input.rb +13 -5
  13. data/lib/vedeu/models/geometry.rb +30 -2
  14. data/lib/vedeu/models/key.rb +39 -0
  15. data/lib/vedeu/output/compositor.rb +30 -76
  16. data/lib/vedeu/output/output.rb +74 -0
  17. data/lib/vedeu/output/viewport.rb +36 -44
  18. data/lib/vedeu/repositories/buffers.rb +5 -18
  19. data/lib/vedeu/repositories/cursors.rb +16 -8
  20. data/lib/vedeu/repositories/events.rb +96 -9
  21. data/lib/vedeu/repositories/focus.rb +21 -20
  22. data/lib/vedeu/repositories/groups.rb +3 -11
  23. data/lib/vedeu/repositories/interfaces.rb +6 -9
  24. data/lib/vedeu/repositories/keymaps.rb +8 -3
  25. data/lib/vedeu/repositories/menus.rb +6 -21
  26. data/lib/vedeu/{models → repositories/models}/buffer.rb +62 -28
  27. data/lib/vedeu/{models → repositories/models}/cursor.rb +8 -2
  28. data/lib/vedeu/{models → repositories/models}/event.rb +7 -0
  29. data/lib/vedeu/repositories/models/group.rb +56 -0
  30. data/lib/vedeu/{models → repositories/models}/interface.rb +6 -0
  31. data/lib/vedeu/{models → repositories/models}/keymap.rb +7 -1
  32. data/lib/vedeu/{models → repositories/models}/menu.rb +9 -0
  33. data/lib/vedeu/{models → repositories/models}/offset.rb +8 -1
  34. data/lib/vedeu/repositories/offsets.rb +17 -12
  35. data/lib/vedeu/support/bounding_area.rb +127 -0
  36. data/lib/vedeu/support/common.rb +8 -0
  37. data/lib/vedeu/support/exceptions.rb +2 -12
  38. data/lib/vedeu/support/model.rb +14 -0
  39. data/lib/vedeu/support/refresh.rb +8 -7
  40. data/lib/vedeu/support/registrar.rb +7 -1
  41. data/lib/vedeu/support/repository.rb +31 -10
  42. data/lib/vedeu/support/sentence.rb +67 -0
  43. data/lib/vedeu/support/terminal.rb +19 -0
  44. data/lib/vedeu/support/trace.rb +2 -5
  45. data/test/integration/api/api_test.rb +97 -0
  46. data/test/integration/api_dsl/dsl_api_test.rb +4 -0
  47. data/test/integration/api_dsl/dsl_composition_test.rb +4 -0
  48. data/test/integration/api_dsl/dsl_defined_test.rb +4 -0
  49. data/test/integration/api_dsl/dsl_helpers_test.rb +4 -0
  50. data/test/integration/api_dsl/dsl_interface_test.rb +4 -0
  51. data/test/integration/api_dsl/dsl_keymap.rb +4 -0
  52. data/test/integration/api_dsl/dsl_line_test.rb +4 -0
  53. data/test/integration/api_dsl/dsl_menu_test.rb +4 -0
  54. data/test/integration/api_dsl/dsl_stream_test.rb +138 -0
  55. data/test/lib/vedeu/api/api_test.rb +1 -25
  56. data/test/lib/vedeu/api/helpers_test.rb +0 -10
  57. data/test/lib/vedeu/{models → colours}/background_test.rb +0 -0
  58. data/test/lib/vedeu/{models → colours}/colour_test.rb +0 -0
  59. data/test/lib/vedeu/{models → colours}/foreground_test.rb +0 -0
  60. data/test/lib/vedeu/{support/colour_translator_test.rb → colours/translator_test.rb} +3 -3
  61. data/test/lib/vedeu/input/input_test.rb +16 -47
  62. data/test/lib/vedeu/models/geometry_test.rb +46 -0
  63. data/test/lib/vedeu/models/group_test.rb +99 -0
  64. data/test/lib/vedeu/models/key_test.rb +41 -0
  65. data/test/lib/vedeu/output/compositor_test.rb +25 -101
  66. data/test/lib/vedeu/output/output_test.rb +108 -0
  67. data/test/lib/vedeu/repositories/buffers_test.rb +0 -8
  68. data/test/lib/vedeu/repositories/cursors_test.rb +34 -0
  69. data/test/lib/vedeu/repositories/focus_test.rb +37 -28
  70. data/test/lib/vedeu/repositories/interfaces_test.rb +1 -1
  71. data/test/lib/vedeu/repositories/keymaps_test.rb +6 -20
  72. data/test/lib/vedeu/repositories/menus_test.rb +0 -6
  73. data/test/lib/vedeu/{models → repositories/models}/buffer_test.rb +24 -27
  74. data/test/lib/vedeu/{models → repositories/models}/cursor_test.rb +0 -0
  75. data/test/lib/vedeu/{models → repositories/models}/event_test.rb +0 -0
  76. data/test/lib/vedeu/{models → repositories/models}/interface_test.rb +0 -0
  77. data/test/lib/vedeu/{models → repositories/models}/keymap_test.rb +0 -0
  78. data/test/lib/vedeu/{models → repositories/models}/menu_test.rb +0 -0
  79. data/test/lib/vedeu/{models → repositories/models}/offset_test.rb +0 -0
  80. data/test/lib/vedeu/support/bounding_area_test.rb +139 -0
  81. data/test/lib/vedeu/support/coercions_test.rb +6 -17
  82. data/test/lib/vedeu/support/grid_test.rb +1 -1
  83. data/test/lib/vedeu/support/model_test.rb +23 -0
  84. data/test/lib/vedeu/support/presentation_test.rb +0 -10
  85. data/test/lib/vedeu/support/refresh_test.rb +2 -2
  86. data/test/lib/vedeu/support/repository_test.rb +63 -64
  87. data/test/lib/vedeu/support/sentence_test.rb +48 -0
  88. data/test/lib/vedeu/support/terminal_test.rb +86 -6
  89. data/test/support/test_classes/all.rb +5 -0
  90. data/test/support/test_classes/coercions.rb +16 -0
  91. data/test/support/test_classes/helpers.rb +19 -0
  92. data/test/support/test_classes/model.rb +23 -0
  93. data/test/support/test_classes/presentation.rb +16 -0
  94. data/test/support/test_classes/repositories.rb +26 -0
  95. data/test/support/test_modules/all.rb +1 -0
  96. data/test/support/test_modules/repository.rb +16 -0
  97. data/test/test_helper.rb +4 -0
  98. data/vedeu.gemspec +3 -3
  99. metadata +95 -50
  100. data/lib/vedeu/output/clear.rb +0 -88
  101. data/lib/vedeu/output/render.rb +0 -50
  102. data/lib/vedeu/repositories/positional.rb +0 -23
  103. data/test/lib/vedeu/output/clear_test.rb +0 -56
  104. data/test/lib/vedeu/output/render_test.rb +0 -100
  105. data/test/lib/vedeu/repositories/positional_test.rb +0 -50
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ module Vedeu
4
+
5
+ describe Key do
6
+
7
+ let(:input) { '' }
8
+ let(:output) { proc { :output } }
9
+
10
+ describe '#initialize' do
11
+ it 'returns a new instance of Key' do
12
+ Key.new(input, output).must_be_instance_of(Key)
13
+ end
14
+ end
15
+
16
+ describe '#input' do
17
+ it 'returns the key defined' do
18
+ Key.new('a', output).input.must_equal('a')
19
+ end
20
+
21
+ context 'alias method #key' do
22
+ it { Key.new('a', output).key.must_equal('a') }
23
+ end
24
+ end
25
+
26
+ describe '#output' do
27
+ end
28
+
29
+ describe '#press' do
30
+ it 'returns the result of calling the proc' do
31
+ Key.new(input, output).press.must_equal(:output)
32
+ end
33
+
34
+ it 'returns a :noop when the output is not a proc' do
35
+ Key.new(input, :output).press.must_equal(:noop)
36
+ end
37
+ end
38
+
39
+ end # Key
40
+
41
+ end # Vedeu
@@ -3,121 +3,45 @@ require 'test_helper'
3
3
  module Vedeu
4
4
 
5
5
  describe Compositor do
6
+ let(:interface) {
7
+ {
8
+ name: 'indium'
9
+ }
10
+ }
11
+ let(:buffer) {
12
+ Buffer.new({ name: 'indium' })
13
+ }
6
14
 
7
15
  before do
8
- Buffers.reset
9
- Interfaces.reset
16
+ Focus.stubs(:cursor).returns("\e[?25l")
10
17
  Terminal.console.stubs(:print)
11
18
  end
12
19
 
13
- describe '.render' do
14
- before do
15
- Vedeu.interface('indium') do
16
- width 10
17
- height 1
18
- end
19
- end
20
-
21
- subject { Compositor.render('indium') }
20
+ describe '#initialize' do
21
+ subject { Compositor.new(interface, buffer) }
22
22
 
23
- context 'when the buffer does not exist' do
24
- it 'raises an exception' do
25
- proc { Compositor.render('') }.must_raise(BufferNotFound)
26
- end
23
+ it 'returns an instance of Compositor' do
24
+ subject.must_be_instance_of(Compositor)
27
25
  end
28
26
 
29
- context 'when the buffer exists' do
30
- it 'returns a Array' do
31
- subject.must_be_instance_of(Array)
32
- end
33
-
34
- context 'when there is new content' do
35
- let(:back) {
36
- { name: 'indium', lines: [{ streams: [{ text: 'back' }] }] }
37
- }
38
-
39
- before { Buffers.add(back) }
40
-
41
- it 'returns the current/front content' do
42
- subject.must_equal([
43
- "\e[1;1H \e[1;1H\e[1;1Hback",
44
- "\e[1;1H\e[?25l"
45
- ])
46
- end
47
-
48
- it 'swaps the new content with the current content' do
49
- Buffers.find('indium').back.must_equal(back)
50
-
51
- subject
52
-
53
- Buffers.find('indium').back.must_equal({})
54
- Buffers.find('indium').front.must_equal(back)
55
- end
56
- end
57
-
58
- context 'when there is no new content' do
59
- let(:front) {
60
- { name: 'indium', lines: [{ streams: [{ text: 'front' }] }] }
61
- }
62
-
63
- before do
64
- Buffers.add(front)
65
- Buffers.find('indium').swap
66
- end
67
-
68
- it 'returns the current/front content' do
69
- subject.must_equal([
70
- "\e[1;1H \e[1;1H\e[1;1Hfront",
71
- "\e[1;1H\e[?25l"
72
- ])
73
- end
74
- end
75
-
76
- context 'when there is no new or current content' do
77
- let(:previous) {
78
- { name: 'indium', lines: [{ streams: [{ text: 'previous' }] }] }
79
- }
80
-
81
- before do
82
- Buffers.add(previous) # puts 'previous' on to 'back'
83
- Buffers.find('indium').swap # puts 'back' ('previous') on to 'front'
84
- Buffers.find('indium').swap # puts 'front' ('previous') on to 'previous'
85
- end
86
-
87
- it 'returns the previous content' do
88
- subject.must_equal([
89
- "\e[1;1H \e[1;1H\e[1;1Hprevious",
90
- "\e[1;1H\e[?25l"
91
- ])
92
- end
93
- end
94
-
95
- context 'when there is no new, current or previous content' do
96
- let(:clear) { { name: 'indium', lines: [] } }
97
-
98
- before { Buffers.add(clear) }
27
+ it 'assigns the interface' do
28
+ subject.instance_variable_get("@interface").must_equal(interface)
29
+ end
99
30
 
100
- it 'returns the escape sequences to clear the interface' do
101
- subject.must_equal(["\e[1;1H \e[1;1H", "\e[1;1H\e[?25l"])
102
- end
103
- end
31
+ it 'assigns the buffer' do
32
+ subject.instance_variable_get("@buffer").must_equal(buffer)
104
33
  end
34
+ end
105
35
 
106
- context 'when the interface cannot be found' do
107
- before do
108
- Interfaces.reset
109
- Buffers.add({ name: 'indium' })
110
- end
36
+ describe '#compose' do
37
+ subject { Compositor.new(interface, buffer).compose }
111
38
 
112
- it 'raises an exception' do
113
- proc { Compositor.render('indium') }.must_raise(InterfaceNotFound)
114
- end
39
+ it 'returns an Array' do
40
+ subject.must_be_instance_of(Array)
115
41
  end
116
- end
117
42
 
118
- describe '#initialize' do
119
- it 'returns an instance of Compositor' do
120
- Compositor.new('indium').must_be_instance_of(Compositor)
43
+ it 'returns the updated interface attributes' do
44
+ subject.must_equal([{}])
121
45
  end
122
46
  end
123
47
 
@@ -0,0 +1,108 @@
1
+ require 'test_helper'
2
+
3
+ module Vedeu
4
+
5
+ describe Output do
6
+ # let(:interface) {
7
+ # Interface.new({
8
+ # name: 'flourine',
9
+ # geometry: {
10
+ # width: 32,
11
+ # height: 3,
12
+ # },
13
+ # lines: lines,
14
+ # colour: colour
15
+ # })
16
+ # }
17
+ # let(:lines) {
18
+ # [
19
+ # {
20
+ # streams: [{ text: 'this is the first' }]
21
+ # },
22
+ # {
23
+ # streams: [{ text: 'this is the second and it is long' }]
24
+ # },
25
+ # {
26
+ # streams: [{ text: 'this is the third, it is even longer and still truncated' }]
27
+ # },
28
+ # {
29
+ # streams: [{ text: 'this should not render' }]
30
+ # }
31
+ # ]
32
+ # }
33
+ # let(:colour) { {} }
34
+
35
+ # before do
36
+ # Buffers.reset
37
+ # Cursors.reset
38
+ # Interfaces.reset
39
+
40
+ # Terminal.console.stubs(:winsize).returns([5, 40])
41
+ # Terminal.console.stubs(:print)
42
+ # end
43
+
44
+ # describe '#initialize' do
45
+ # it 'returns an instance of itself' do
46
+ # Output.new(interface).must_be_instance_of(Output)
47
+ # end
48
+ # end
49
+
50
+ # describe '.render' do
51
+ # it 'returns the content for the interface' do
52
+ # Output.render(interface).must_equal(
53
+ # "\e[1;1H \e[1;1H" \
54
+ # "\e[2;1H \e[2;1H" \
55
+ # "\e[3;1H \e[3;1H" \
56
+ # "\e[1;1Hthis is the first" \
57
+ # "\e[2;1Hthis is the second and it is lon" \
58
+ # "\e[3;1Hthis is the third, it is even lo"
59
+ # )
60
+ # end
61
+
62
+ # context 'when there are no streams of text' do
63
+ # let(:lines) { [] }
64
+
65
+ # it 'returns a blank interface' do
66
+ # Output.render(interface).must_equal(
67
+ # "\e[1;1H \e[1;1H" \
68
+ # "\e[2;1H \e[2;1H" \
69
+ # "\e[3;1H \e[3;1H"
70
+ # )
71
+ # end
72
+ # end
73
+
74
+ # context 'when lines have streams which are empty' do
75
+ # let(:lines) {
76
+ # [
77
+ # {
78
+ # streams: [{ text: 'this is the first' }]
79
+ # }, {
80
+ # streams: { text: '' }
81
+ # }, {
82
+ # streams: [
83
+ # { text: 'this is the third, ' },
84
+ # { text: 'it is even longer ' },
85
+ # { text: 'and still truncated' }
86
+ # ]
87
+ # }, {
88
+ # streams: [{ text: 'this should not render' }]
89
+ # }
90
+ # ]
91
+ # }
92
+
93
+ # it 'skips lines' do
94
+ # Output.render(interface).must_equal(
95
+ # "\e[1;1H \e[1;1H" \
96
+ # "\e[2;1H \e[2;1H" \
97
+ # "\e[3;1H \e[3;1H" \
98
+ # "\e[1;1Hthis is the first" \
99
+ # "\e[2;1H" \
100
+ # "\e[3;1Hthis is the third, it is even lo"
101
+ # )
102
+ # end
103
+ # end
104
+ # end
105
+
106
+ end # Output
107
+
108
+ end # Vedeu
@@ -32,14 +32,6 @@ module Vedeu
32
32
  end
33
33
  end
34
34
 
35
- describe '.update' do
36
- let(:buffer) { Buffer.new({ name: 'einsteinium' }) }
37
-
38
- subject { Buffers.update(buffer) }
39
-
40
- it { subject.must_equal(true) }
41
- end
42
-
43
35
  end # Buffers
44
36
 
45
37
  end # Vedeu
@@ -6,9 +6,43 @@ module Vedeu
6
6
 
7
7
  before do
8
8
  Cursors.reset
9
+ Offsets.reset
9
10
  Registrar.record({ name: 'chromium' })
10
11
  end
11
12
 
13
+ describe '#add' do
14
+ let(:attributes) { { name: 'chromium' } }
15
+
16
+ it 'raises an exception if a :name attribute is not provided' do
17
+ proc { Offsets.add({ no_name: 'no_name' }) }
18
+ .must_raise(MissingRequired)
19
+ end
20
+
21
+ it 'returns a new instance of Offset once stored' do
22
+ Offsets.add({ name: 'praseodymium' }).must_be_instance_of(Offset)
23
+ end
24
+
25
+ it 'returns a new Cursor after registering' do
26
+ Cursors.add(attributes).must_be_instance_of(Cursor)
27
+ end
28
+
29
+ it 'returns a new Cursor after updating' do
30
+ Cursors.update(attributes).must_be_instance_of(Cursor)
31
+ end
32
+
33
+ context 'when the attributes do not have the :name key' do
34
+ let(:attributes) { { no_name_key: 'some_value' } }
35
+
36
+ it 'raises an exception' do
37
+ proc { Cursors.update(attributes) }.must_raise(MissingRequired)
38
+ end
39
+
40
+ it 'raises an exception' do
41
+ proc { Cursors.add(attributes) }.must_raise(MissingRequired)
42
+ end
43
+ end
44
+ end
45
+
12
46
  describe '#hide' do
13
47
  it 'sets the state attribute of the Cursor to :hide' do
14
48
  cursor = Cursors.hide
@@ -9,52 +9,46 @@ module Vedeu
9
9
 
10
10
  describe '#add' do
11
11
  it 'adds an interface to storage' do
12
- Focus.add({ name: 'thallium' }).must_equal(['thallium'])
12
+ Focus.add('thallium').must_equal(['thallium'])
13
13
  end
14
14
 
15
15
  it 'does not add it again if already exists' do
16
- Focus.add({ name: 'thallium' })
17
- Focus.add({ name: 'thallium' })
16
+ Focus.add('thallium')
17
+ Focus.add('thallium')
18
18
  Focus.registered.must_equal(['thallium'])
19
19
  end
20
20
 
21
21
  it 'adds the interface to storage focussed' do
22
- Focus.add({ name: 'thallium' })
23
- Focus.add({ name: 'lead', focus: true })
22
+ Focus.add('thallium')
23
+ Focus.add('lead', true)
24
24
  Focus.registered.must_equal(['lead', 'thallium'])
25
25
  end
26
26
 
27
27
  it 'adds the interface to storage unfocussed' do
28
- Focus.add({ name: 'thallium' })
29
- Focus.add({ name: 'lead' })
28
+ Focus.add('thallium')
29
+ Focus.add('lead')
30
30
  Focus.registered.must_equal(['thallium', 'lead'])
31
31
  end
32
-
33
- it 'raises an exception if the attributes does not have a :name key' do
34
- attributes = { no_name_key: '' }
35
-
36
- proc { Focus.add(attributes) }.must_raise(MissingRequired)
37
- end
38
32
  end
39
33
 
40
34
  describe '#by_name' do
41
35
  it 'the named interface is focussed when the method is called' do
42
- Focus.add({ name: 'thallium' })
43
- Focus.add({ name: 'lead' })
44
- Focus.add({ name: 'bismuth' })
36
+ Focus.add('thallium')
37
+ Focus.add('lead')
38
+ Focus.add('bismuth')
45
39
  Focus.by_name('lead').must_equal('lead')
46
40
  end
47
41
 
48
42
  it 'raises an exception if the interface does not exist' do
49
- proc { Focus.by_name('not_found') }.must_raise(InterfaceNotFound)
43
+ proc { Focus.by_name('not_found') }.must_raise(ModelNotFound)
50
44
  end
51
45
  end
52
46
 
53
47
  describe '#current' do
54
48
  it 'returns the name of the interface currently in focus' do
55
- Focus.add({ name: 'thallium' })
56
- Focus.add({ name: 'lead' })
57
- Focus.add({ name: 'bismuth' })
49
+ Focus.add('thallium')
50
+ Focus.add('lead')
51
+ Focus.add('bismuth')
58
52
  Focus.current.must_equal('thallium')
59
53
  end
60
54
 
@@ -63,6 +57,18 @@ module Vedeu
63
57
  end
64
58
  end
65
59
 
60
+ describe '#cursor' do
61
+ before do
62
+ Interfaces.add({ name: 'thallium' })
63
+ Focus.add('thallium')
64
+ end
65
+
66
+ it 'returns the escape sequence to render the cursor for the focussed ' \
67
+ 'interface' do
68
+ Focus.cursor.must_equal("\e[1;1H\e[?25l")
69
+ end
70
+ end
71
+
66
72
  describe '#current?' do
67
73
  before { Focus.stubs(:current).returns('lead') }
68
74
 
@@ -77,9 +83,9 @@ module Vedeu
77
83
 
78
84
  describe '#next_item' do
79
85
  it 'the next interface is focussed when the method is called' do
80
- Focus.add({ name: 'thallium' })
81
- Focus.add({ name: 'lead' })
82
- Focus.add({ name: 'bismuth' })
86
+ Focus.add('thallium')
87
+ Focus.add('lead')
88
+ Focus.add('bismuth')
83
89
  Focus.next_item.must_equal('lead')
84
90
  end
85
91
 
@@ -90,9 +96,9 @@ module Vedeu
90
96
 
91
97
  describe '#prev_item' do
92
98
  it 'the previous interface is focussed when the method is called' do
93
- Focus.add({ name: 'thallium' })
94
- Focus.add({ name: 'lead' })
95
- Focus.add({ name: 'bismuth' })
99
+ Focus.add('thallium')
100
+ Focus.add('lead')
101
+ Focus.add('bismuth')
96
102
  Focus.prev_item.must_equal('bismuth')
97
103
  end
98
104
 
@@ -102,9 +108,12 @@ module Vedeu
102
108
  end
103
109
 
104
110
  describe '#refresh' do
105
- it 'triggers the event to refresh the interface current in focus' do
106
- Focus.add({ name: 'thallium' })
111
+ before do
112
+ Focus.add('thallium')
113
+ Vedeu.stubs(:trigger).returns([])
114
+ end
107
115
 
116
+ it 'triggers the event to refresh the interface current in focus' do
108
117
  Focus.refresh.must_equal([])
109
118
  end
110
119
  end