vedeu 0.2.10 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
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