vedeu 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -9
  3. data/docs/api.md +70 -42
  4. data/elements.txt +118 -0
  5. data/lib/vedeu.rb +14 -4
  6. data/lib/vedeu/api/api.rb +67 -24
  7. data/lib/vedeu/api/composition.rb +19 -0
  8. data/lib/vedeu/api/defined.rb +7 -0
  9. data/lib/vedeu/api/interface.rb +103 -75
  10. data/lib/vedeu/api/keymap.rb +62 -0
  11. data/lib/vedeu/api/menu.rb +3 -1
  12. data/lib/vedeu/configuration.rb +24 -6
  13. data/lib/vedeu/models/attributes/coercions.rb +18 -26
  14. data/lib/vedeu/models/attributes/colour_translator.rb +7 -7
  15. data/lib/vedeu/models/attributes/presentation.rb +12 -1
  16. data/lib/vedeu/models/geometry.rb +5 -1
  17. data/lib/vedeu/models/interface.rb +6 -47
  18. data/lib/vedeu/models/keymap.rb +66 -0
  19. data/lib/vedeu/models/line.rb +3 -1
  20. data/lib/vedeu/models/stream.rb +10 -1
  21. data/lib/vedeu/models/style.rb +10 -1
  22. data/lib/vedeu/output/compositor.rb +3 -0
  23. data/lib/vedeu/output/refresh.rb +16 -74
  24. data/lib/vedeu/output/render.rb +44 -17
  25. data/lib/vedeu/output/view.rb +3 -0
  26. data/lib/vedeu/repositories/buffers.rb +32 -42
  27. data/lib/vedeu/repositories/events.rb +8 -11
  28. data/lib/vedeu/repositories/focus.rb +15 -13
  29. data/lib/vedeu/repositories/groups.rb +20 -2
  30. data/lib/vedeu/repositories/interfaces.rb +22 -2
  31. data/lib/vedeu/repositories/keymap_validator.rb +104 -0
  32. data/lib/vedeu/repositories/keymaps.rb +239 -0
  33. data/lib/vedeu/repositories/menus.rb +12 -3
  34. data/lib/vedeu/support/common.rb +2 -2
  35. data/lib/vedeu/support/cursor.rb +3 -0
  36. data/lib/vedeu/support/event.rb +48 -7
  37. data/lib/vedeu/support/grid.rb +1 -1
  38. data/lib/vedeu/support/registrar.rb +66 -0
  39. data/lib/vedeu/support/trace.rb +71 -12
  40. data/test/lib/vedeu/api/api_test.rb +27 -9
  41. data/test/lib/vedeu/api/composition_test.rb +10 -0
  42. data/test/lib/vedeu/api/defined_test.rb +14 -0
  43. data/test/lib/vedeu/api/interface_test.rb +86 -85
  44. data/test/lib/vedeu/api/keymap_test.rb +61 -0
  45. data/test/lib/vedeu/configuration_test.rb +12 -0
  46. data/test/lib/vedeu/models/attributes/coercions_test.rb +3 -4
  47. data/test/lib/vedeu/models/interface_test.rb +0 -43
  48. data/test/lib/vedeu/models/keymap_test.rb +19 -0
  49. data/test/lib/vedeu/models/style_test.rb +10 -0
  50. data/test/lib/vedeu/output/refresh_test.rb +0 -12
  51. data/test/lib/vedeu/output/render_test.rb +51 -0
  52. data/test/lib/vedeu/repositories/buffers_test.rb +39 -12
  53. data/test/lib/vedeu/repositories/events_test.rb +6 -0
  54. data/test/lib/vedeu/repositories/focus_test.rb +12 -0
  55. data/test/lib/vedeu/repositories/keymap_validator_test.rb +81 -0
  56. data/test/lib/vedeu/repositories/keymaps_test.rb +254 -0
  57. data/test/lib/vedeu/support/common_test.rb +26 -0
  58. data/test/lib/vedeu/support/registrar_test.rb +68 -0
  59. data/vedeu.gemspec +1 -1
  60. metadata +18 -2
@@ -115,6 +115,12 @@ module Vedeu
115
115
  debug: false,
116
116
  interactive: true,
117
117
  once: false,
118
+ system_keys: {
119
+ exit: "q",
120
+ focus_next: :tab,
121
+ focus_prev: :shift_tab,
122
+ mode_switch: :escape
123
+ },
118
124
  terminal_mode: :raw,
119
125
  trace: false
120
126
  }
@@ -131,6 +137,12 @@ module Vedeu
131
137
  once: true,
132
138
  colour_mode: 16777216,
133
139
  debug: false,
140
+ system_keys: {
141
+ exit: "q",
142
+ focus_next: :tab,
143
+ focus_prev: :shift_tab,
144
+ mode_switch: :escape
145
+ },
134
146
  terminal_mode: :raw,
135
147
  trace: false
136
148
  }
@@ -9,7 +9,6 @@ module Vedeu
9
9
  def initialize(attributes = {})
10
10
  @attributes = attributes
11
11
  @name = attributes[:name]
12
- @parent = attributes[:parent]
13
12
  end
14
13
  end
15
14
 
@@ -30,7 +29,7 @@ module Vedeu
30
29
  it 'returns a collection of models when a single hash' do
31
30
  coerced = TestClass.coercer({ :name => 'test1' })
32
31
  coerced.must_be_instance_of(Array)
33
- coerced.first.attributes.must_equal({ name: "test1", parent: nil })
32
+ coerced.first.attributes.must_equal({ name: "test1" })
34
33
  end
35
34
 
36
35
  it 'returns a collection of models when multiple hashes' do
@@ -39,14 +38,14 @@ module Vedeu
39
38
  ])
40
39
  coerced.size.must_equal(2)
41
40
  coerced.map(&:attributes).must_equal(
42
- [{ name: "test1", parent: nil }, { name: "test2", parent: nil }]
41
+ [{ name: "test1" }, { name: "test2" }]
43
42
  )
44
43
  end
45
44
 
46
45
  it 'returns a collection of models when a single array' do
47
46
  coerced = TestClass.coercer([{ :name => 'test3' }])
48
47
  coerced.size.must_equal(1)
49
- coerced.first.attributes.must_equal({ name: "test3", parent: nil })
48
+ coerced.first.attributes.must_equal({ name: "test3" })
50
49
  end
51
50
  end
52
51
  end
@@ -95,48 +95,5 @@ module Vedeu
95
95
  end
96
96
  end
97
97
 
98
- describe '#to_s' do
99
- it 'returns an string' do
100
- Interface.new({
101
- name: '#to_s',
102
- lines: [],
103
- colour: {
104
- foreground: '#ff0000',
105
- background: '#000000'
106
- },
107
- geometry: {
108
- width: 9,
109
- height: 3
110
- }
111
- }).to_s.must_equal(
112
- "\e[38;2;255;0;0m\e[48;2;0;0;0m" \
113
- "\e[1;1H \e[1;1H" \
114
- "\e[2;1H \e[2;1H" \
115
- "\e[3;1H \e[3;1H\e[?25h"
116
- )
117
- end
118
- end
119
-
120
- describe '#clear' do
121
- it 'delegates to the Clear class to return an empty interface' do
122
- Interface.new({
123
- name: '#to_s',
124
- lines: [],
125
- colour: {
126
- foreground: '#ff0000',
127
- background: '#000000'
128
- },
129
- geometry: {
130
- width: 9,
131
- height: 3
132
- }
133
- }).clear.must_equal(
134
- "\e[38;2;255;0;0m\e[48;2;0;0;0m" \
135
- "\e[1;1H \e[1;1H" \
136
- "\e[2;1H \e[2;1H" \
137
- "\e[3;1H \e[3;1H"
138
- )
139
- end
140
- end
141
98
  end
142
99
  end
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ module Vedeu
4
+ describe Keymap do
5
+
6
+ describe '.define' do
7
+ it '' do
8
+ skip
9
+ end
10
+ end
11
+
12
+ describe '#initialize' do
13
+ it 'returns an instance of itself' do
14
+ Keymap.new.must_be_instance_of(Keymap)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -10,6 +10,16 @@ module Vedeu
10
10
  end
11
11
  end
12
12
 
13
+ describe '#attributes' do
14
+ it 'returns an attributes hash for this instance' do
15
+ Style.new(['bold']).attributes.must_equal(
16
+ {
17
+ style: ['bold']
18
+ }
19
+ )
20
+ end
21
+ end
22
+
13
23
  describe '#to_s' do
14
24
  describe 'for a single style' do
15
25
  let(:values) { 'normal' }
@@ -2,18 +2,6 @@ require 'test_helper'
2
2
 
3
3
  module Vedeu
4
4
  describe Refresh do
5
- describe '.add_interface' do
6
- it 'returns false when provided with no attributes' do
7
- Refresh.add_interface({}).must_equal(false)
8
- end
9
- end
10
-
11
- describe '.add_group' do
12
- it 'returns false when provided with no attributes' do
13
- Refresh.add_group({}).must_equal(false)
14
- end
15
- end
16
-
17
5
  describe '.all' do
18
6
  it 'returns an empty collection when there are no registered ' \
19
7
  'interfaces' do
@@ -131,6 +131,57 @@ module Vedeu
131
131
  )
132
132
  end
133
133
 
134
+ it 'returns to using the presentation attributes of the line after a ' \
135
+ 'stream finishes' do
136
+ Vedeu.interface 'oxygen' do
137
+ width 40
138
+ height 2
139
+ end
140
+
141
+ class OxygenView < Vedeu::View
142
+ def render
143
+ Vedeu.view 'oxygen' do
144
+ line do
145
+ colour background: '#000000', foreground: '#ffffff'
146
+ stream do
147
+ text 'the grass is '
148
+ end
149
+ stream do
150
+ colour foreground: '#00ff00'
151
+ text 'green'
152
+ end
153
+ stream do
154
+ text ' and the sky is '
155
+ end
156
+ stream do
157
+ colour foreground: '#0000ff'
158
+ text 'blue'
159
+ end
160
+ stream do
161
+ text '.'
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ IO.console.stub(:print, nil) do
169
+ OxygenView.render
170
+
171
+ Compositor.render('oxygen').must_equal([
172
+ "\e[1;1H \e[1;1H" \
173
+ "\e[2;1H \e[2;1H" \
174
+ "\e[1;1H\e[38;2;255;255;255m\e[48;2;0;0;0m" \
175
+ "the grass is \e[38;2;255;255;255m\e[48;2;0;0;0m" \
176
+ "\e[38;2;0;255;0mgreen\e[38;2;255;255;255m\e[48;2;0;0;0m" \
177
+ " and the sky is \e[38;2;255;255;255m\e[48;2;0;0;0m" \
178
+ "\e[38;2;0;0;255mblue\e[38;2;255;255;255m\e[48;2;0;0;0m" \
179
+ ".\e[38;2;255;255;255m\e[48;2;0;0;0m" \
180
+ "\e[?25h"
181
+ ])
182
+ end
183
+ end
184
+
134
185
  end
135
186
  end
136
187
  end
@@ -3,45 +3,72 @@ require 'test_helper'
3
3
  module Vedeu
4
4
  describe Buffers do
5
5
 
6
- describe '.create' do
7
- end
8
-
9
6
  describe '.add' do
10
- end
7
+ before { Buffers.reset }
11
8
 
12
- describe '.find' do
13
- context 'when the buffer does not exist by this name' do
9
+ it 'returns the name of the buffer added to storage' do
10
+ Buffers.add({ name: 'molybdenum' }).must_equal('molybdenum')
14
11
  end
15
12
 
16
- context 'when the buffer can be found by name' do
13
+ context 'when the buffer is already registered' do
14
+ it 'retrieves the buffer in storage, and adds the attributes to the ' \
15
+ 'back buffer, preserving the front which may already have content' do
16
+ skip
17
+ end
18
+ end
19
+
20
+ context 'when the buffer was not registered' do
21
+ it 'stores a new buffer by name, and adds the attributes to the back ' \
22
+ 'buffer' do
23
+ skip
24
+ end
17
25
  end
18
26
  end
19
27
 
20
- describe '.latest' do
28
+ describe '.find' do
21
29
  context 'when the buffer does not exist by this name' do
30
+ it '' do
31
+ skip
32
+ end
22
33
  end
23
34
 
24
35
  context 'when the buffer can be found by name' do
36
+ it '' do
37
+ skip
38
+ end
25
39
  end
26
40
  end
27
41
 
28
- describe '.content' do
42
+ describe '.latest' do
29
43
  context 'when the buffer does not exist by this name' do
44
+ it '' do
45
+ skip
46
+ end
30
47
  end
31
48
 
32
49
  context 'when the buffer can be found by name' do
50
+ it '' do
51
+ skip
52
+ end
33
53
  end
34
54
  end
35
55
 
36
- describe '.swap_buffers' do
37
- context 'when the buffer does not exist by this name' do
56
+ describe '.registered' do
57
+ it '' do
58
+ skip
38
59
  end
60
+ end
39
61
 
40
- context 'when the buffer can be found by name' do
62
+ describe '.registered>' do
63
+ it '' do
64
+ skip
41
65
  end
42
66
  end
43
67
 
44
68
  describe '.reset' do
69
+ it '' do
70
+ skip
71
+ end
45
72
  end
46
73
 
47
74
  end
@@ -37,6 +37,12 @@ module Vedeu
37
37
  end
38
38
  end
39
39
 
40
+ describe '#registered?' do
41
+ it '' do
42
+ skip
43
+ end
44
+ end
45
+
40
46
  describe '#trigger' do
41
47
  it 'returns a collection containing the event when the event is ' \
42
48
  'pre-registered' do
@@ -70,5 +70,17 @@ module Vedeu
70
70
  Focus.registered.must_equal(['thallium', 'lead', 'bismuth'])
71
71
  end
72
72
  end
73
+
74
+ describe '.registered?' do
75
+ it '' do
76
+ skip
77
+ end
78
+ end
79
+
80
+ describe '.reset' do
81
+ it '' do
82
+ skip
83
+ end
84
+ end
73
85
  end
74
86
  end
@@ -0,0 +1,81 @@
1
+ require 'test_helper'
2
+
3
+ module Vedeu
4
+ describe KeymapValidator do
5
+ let(:storage) {
6
+ {
7
+ 'dubnium' => {
8
+ 'a' => proc { :do_something }
9
+ },
10
+ '_global_keymap_' => {
11
+ 'g' => proc { :do_something }
12
+ }
13
+ }
14
+ }
15
+ let(:key) { 'a' }
16
+ let(:interface) { 'dubnium' }
17
+
18
+ describe '.check' do
19
+ context 'when already in use as a system key' do
20
+ it 'returns false with a message' do
21
+ result = KeymapValidator.check(storage, :shift_tab, interface)
22
+ result.must_include(false)
23
+ result.last.must_match(/by the system/)
24
+ end
25
+ end
26
+
27
+ context 'when already in use as a global key' do
28
+ it 'returns false with a message' do
29
+ result = KeymapValidator.check(storage, 'g', interface)
30
+ result.must_include(false)
31
+ result.last.must_match(/as a global key/)
32
+ end
33
+ end
34
+
35
+ context 'when already in use by the interface' do
36
+ it 'returns false with a message' do
37
+ result = KeymapValidator.check(storage, 'a', interface)
38
+ result.must_include(false)
39
+ result.last.must_match(/by this interface/)
40
+ end
41
+ end
42
+
43
+ context 'when attempting to register a global key which is already in ' \
44
+ 'use by an interface' do
45
+ it 'returns false with a message' do
46
+ result = KeymapValidator.check(storage, 'a', '')
47
+ result.must_include(false)
48
+ result.last.must_match(/therefore cannot be global/)
49
+ end
50
+ end
51
+
52
+ context 'when valid as a global key' do
53
+ it 'returns true with a message' do
54
+ result = KeymapValidator.check(storage, 'h', '')
55
+ result.must_include(true)
56
+ result.last.must_match(/can be registered/)
57
+ end
58
+ end
59
+
60
+ context 'when valid as an interface key' do
61
+ it 'returns true with a message' do
62
+ result = KeymapValidator.check(storage, 'b', 'dubnium')
63
+ result.must_include(true)
64
+ result.last.must_match(/can be registered/)
65
+ end
66
+ end
67
+ end
68
+
69
+ describe '#initialize' do
70
+ it 'returns an instance of itself' do
71
+ storage = {}
72
+ key = ''
73
+ interface = ''
74
+
75
+ KeymapValidator.new(storage, key, interface)
76
+ .must_be_instance_of(KeymapValidator)
77
+ end
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,254 @@
1
+ require 'test_helper'
2
+
3
+ module Vedeu
4
+ describe Keymaps do
5
+
6
+ describe '#add' do
7
+ before { Keymaps.reset }
8
+
9
+ it 'returns false when there are no keys defined' do
10
+ attributes = {}
11
+
12
+ Keymaps.add(attributes).must_equal(false)
13
+ end
14
+
15
+ it 'returns true when the key was registered with keymap storage' do
16
+ attributes = { interfaces: ['gold'], keys: [{ 'a' => proc { :gold } }] }
17
+
18
+ Keymaps.add(attributes).must_equal(true)
19
+ end
20
+ end
21
+
22
+ describe '#all' do
23
+ before { Keymaps.reset }
24
+
25
+ it 'returns all stored keymaps' do
26
+ Keymaps.all.must_equal({ '_global_keymap_' => {} })
27
+ end
28
+ end
29
+
30
+ describe '#find' do
31
+ let(:attributes) {
32
+ {
33
+ interfaces: ['flerovium'],
34
+ keys: [{ key: 'u', action: proc { :some_action } }]
35
+ }
36
+ }
37
+
38
+ before do
39
+ Keymaps.reset
40
+ Keymaps.add(attributes)
41
+ end
42
+
43
+ it 'returns false when the named keymap cannot be found' do
44
+ Keymaps.find('vanadium').must_equal({})
45
+ end
46
+
47
+ it 'returns the keymap when the named keymap was found' do
48
+ Keymaps.find('flerovium').wont_be_empty
49
+ end
50
+ end
51
+
52
+ describe '#global_key?' do
53
+ before do
54
+ Keymaps.reset
55
+ Keymaps.stubs(:global_keys).returns(['i', 'j'])
56
+ end
57
+
58
+ it 'returns false when the key is not registered as a global key' do
59
+ Keymaps.global_key?('h').must_equal(false)
60
+ end
61
+
62
+ it 'returns true when the key is registered as a global key' do
63
+ Keymaps.global_key?('j').must_equal(true)
64
+ end
65
+ end
66
+
67
+ describe '#global_keys' do
68
+ let(:attributes) {
69
+ {
70
+ keys: [
71
+ {
72
+ key: 'a', action: proc { :action_a }
73
+ },{
74
+ key: 'b', action: proc { :action_b }
75
+ },{
76
+ key: 'c', action: proc { :action_c }
77
+ }
78
+ ]
79
+ }
80
+ }
81
+
82
+ before do
83
+ Keymaps.reset
84
+ Keymaps.add(attributes)
85
+ end
86
+
87
+ it 'returns the defined global keys' do
88
+ Keymaps.global_keys.must_equal(['a', 'b', 'c'])
89
+ end
90
+ end
91
+
92
+ describe '#interface_key?' do
93
+ before do
94
+ Keymaps.reset
95
+ Keymaps.stubs(:interface_keys).returns(['g', 'h'])
96
+ end
97
+
98
+ it 'returns false when the key is not registered with an interface' do
99
+ Keymaps.interface_key?('f').must_equal(false)
100
+ end
101
+
102
+ it 'returns true when the key is registered with an interface' do
103
+ Keymaps.interface_key?('g').must_equal(true)
104
+ end
105
+
106
+ context 'when the interface argument is provided' do
107
+ before do
108
+ Keymaps.stubs(:find).returns({ 'j' => proc { :some_action } })
109
+ end
110
+
111
+ it 'return false when the key is not registered with the specified ' \
112
+ 'interface' do
113
+ Keymaps.interface_key?('k', 'cadmium').must_equal(false)
114
+ end
115
+
116
+ it 'return true when the key is registered with the specified ' \
117
+ 'interface' do
118
+ Keymaps.interface_key?('j', 'cadmium').must_equal(true)
119
+ end
120
+ end
121
+ end
122
+
123
+ describe '#interface_keys' do
124
+ let(:rhodium_attributes) {
125
+ {
126
+ interfaces: ['rhodium'],
127
+ keys: [
128
+ {
129
+ key: 'd', action: proc { :action_d }
130
+ },{
131
+ key: 'e', action: proc { :action_e }
132
+ }
133
+ ]
134
+ }
135
+ }
136
+ let(:magnesium_attributes) {
137
+ {
138
+ interfaces: ['magnesium'],
139
+ keys: [
140
+ {
141
+ key: 'e', action: proc { :action_e }
142
+ },{
143
+ key: 'f', action: proc { :action_g }
144
+ }
145
+ ]
146
+ }
147
+ }
148
+
149
+ before do
150
+ Keymaps.reset
151
+ Keymaps.add(rhodium_attributes)
152
+ Keymaps.add(magnesium_attributes)
153
+ end
154
+
155
+ it 'returns the defined keys for all interfaces' do
156
+ Keymaps.interface_keys.must_equal(['d', 'e', 'f'])
157
+ end
158
+ end
159
+
160
+ describe '#registered' do
161
+ before { Keymaps.reset }
162
+
163
+ it 'returns a collection of the interface names of all registered ' \
164
+ 'keymaps' do
165
+ Keymaps.registered.must_equal(['_global_keymap_'])
166
+ end
167
+ end
168
+
169
+ describe '#registered?' do
170
+ it 'returns false when the named keymap is not registered' do
171
+ Keymaps.registered?('vanadium').must_equal(false)
172
+ end
173
+
174
+ it 'returns true when the named keymap is registered' do
175
+ Keymaps.registered?('_global_keymap_').must_equal(true)
176
+ end
177
+ end
178
+
179
+ describe '#reset' do
180
+ it 'removes all stored keymaps' do
181
+ Keymaps.reset.must_equal({ '_global_keymap_' => {} })
182
+ end
183
+ end
184
+
185
+ describe '#system_key?' do
186
+ it 'returns false when the key is not registered as a system key' do
187
+ Keymaps.system_key?('r').must_equal(false)
188
+ end
189
+
190
+ it 'returns true when the key is registered as a system key' do
191
+ Keymaps.system_key?('q').must_equal(true)
192
+ end
193
+ end
194
+
195
+ describe '#system_keys' do
196
+ it 'returns the defined system keys' do
197
+ Keymaps.system_keys.must_equal(['q', :tab, :shift_tab, :escape])
198
+ end
199
+ end
200
+
201
+ describe '#use' do
202
+ let(:meitnerium_attributes) {
203
+ {
204
+ interfaces: ['meitnerium'],
205
+ keys: [{
206
+ key: 'm', action: proc { :key_m_pressed }
207
+ }]
208
+ }
209
+ }
210
+ let(:global_attributes) {
211
+ {
212
+ keys: [{
213
+ key: 'o', action: proc { :key_o_pressed }
214
+ }]
215
+ }
216
+ }
217
+
218
+ before do
219
+ Keymaps.reset
220
+ Keymaps.add(meitnerium_attributes)
221
+ Keymaps.add(global_attributes)
222
+ Vedeu::Focus.stubs(:current).returns('meitnerium')
223
+ Vedeu::Configuration.stubs(:system_keys).returns({ :key_p_pressed => 'p' })
224
+ Vedeu.stubs(:trigger).returns(:system_key_p_pressed)
225
+ end
226
+
227
+ context 'when not registered' do
228
+ it 'returns false' do
229
+ Keymaps.use('l').must_equal(false)
230
+ end
231
+ end
232
+
233
+ context 'when registered as an interface key and the interface is in ' \
234
+ 'focus' do
235
+ it 'returns the result of the keypress' do
236
+ Keymaps.use('m').must_equal(:key_m_pressed)
237
+ end
238
+ end
239
+
240
+ context 'when registered as a global key' do
241
+ it 'returns the result of the keypress' do
242
+ Keymaps.use('o').must_equal(:key_o_pressed)
243
+ end
244
+ end
245
+
246
+ context 'when registered as a system key' do
247
+ it 'returns the result of the keypress' do
248
+ Keymaps.use('p').must_equal(:system_key_p_pressed)
249
+ end
250
+ end
251
+ end
252
+
253
+ end
254
+ end