vedeu 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/docs/api.md +2 -0
  3. data/docs/events.md +0 -4
  4. data/examples/cursor_app/cursor_app.rb +56 -44
  5. data/lib/vedeu/api/api.rb +4 -6
  6. data/lib/vedeu/api/composition.rb +3 -7
  7. data/lib/vedeu/api/interface.rb +2 -3
  8. data/lib/vedeu/api/menu.rb +5 -3
  9. data/lib/vedeu/api/stream.rb +34 -0
  10. data/lib/vedeu/application.rb +4 -7
  11. data/lib/vedeu/configuration/api.rb +0 -5
  12. data/lib/vedeu/configuration/cli.rb +0 -1
  13. data/lib/vedeu/configuration/configuration.rb +0 -12
  14. data/lib/vedeu/input/input.rb +0 -3
  15. data/lib/vedeu/launcher.rb +0 -1
  16. data/lib/vedeu/models/{attributes/background.rb → background.rb} +0 -4
  17. data/lib/vedeu/models/char.rb +43 -0
  18. data/lib/vedeu/models/colour.rb +0 -1
  19. data/lib/vedeu/models/composition.rb +4 -3
  20. data/lib/vedeu/models/cursor.rb +70 -146
  21. data/lib/vedeu/models/{attributes/foreground.rb → foreground.rb} +0 -4
  22. data/lib/vedeu/models/geometry.rb +19 -20
  23. data/lib/vedeu/models/interface.rb +36 -5
  24. data/lib/vedeu/models/keymap.rb +7 -4
  25. data/lib/vedeu/models/line.rb +31 -11
  26. data/lib/vedeu/models/offset.rb +84 -0
  27. data/lib/vedeu/models/stream.rb +37 -13
  28. data/lib/vedeu/models/style.rb +0 -1
  29. data/lib/vedeu/output/area.rb +284 -0
  30. data/lib/vedeu/output/clear.rb +2 -4
  31. data/lib/vedeu/output/compositor.rb +0 -4
  32. data/lib/vedeu/output/refresh.rb +1 -2
  33. data/lib/vedeu/output/render.rb +12 -163
  34. data/lib/vedeu/output/view.rb +0 -2
  35. data/lib/vedeu/output/viewport.rb +132 -0
  36. data/lib/vedeu/repositories/buffers.rb +11 -22
  37. data/lib/vedeu/repositories/cursors.rb +20 -47
  38. data/lib/vedeu/repositories/events.rb +2 -1
  39. data/lib/vedeu/repositories/focus.rb +16 -16
  40. data/lib/vedeu/repositories/groups.rb +1 -4
  41. data/lib/vedeu/repositories/interfaces.rb +10 -3
  42. data/lib/vedeu/repositories/keymaps.rb +0 -3
  43. data/lib/vedeu/repositories/menus.rb +0 -2
  44. data/lib/vedeu/repositories/offsets.rb +47 -0
  45. data/lib/vedeu/{models/attributes → support}/coercions.rb +0 -0
  46. data/lib/vedeu/{models/attributes → support}/colour_translator.rb +0 -16
  47. data/lib/vedeu/support/esc.rb +0 -22
  48. data/lib/vedeu/support/event.rb +1 -17
  49. data/lib/vedeu/support/exceptions.rb +0 -3
  50. data/lib/vedeu/support/grid.rb +0 -3
  51. data/lib/vedeu/support/log.rb +13 -14
  52. data/lib/vedeu/support/move.rb +50 -0
  53. data/lib/vedeu/support/position.rb +17 -9
  54. data/lib/vedeu/{models/attributes → support}/presentation.rb +1 -4
  55. data/lib/vedeu/support/registrar.rb +2 -2
  56. data/lib/vedeu/support/repository.rb +23 -2
  57. data/lib/vedeu/support/terminal.rb +0 -2
  58. data/lib/vedeu/support/trace.rb +0 -11
  59. data/lib/vedeu.rb +11 -5
  60. data/test/lib/vedeu/api/api_test.rb +14 -5
  61. data/test/lib/vedeu/api/composition_test.rb +9 -26
  62. data/test/lib/vedeu/api/keymap_test.rb +1 -1
  63. data/test/lib/vedeu/api/menu_test.rb +6 -0
  64. data/test/lib/vedeu/api/stream_test.rb +32 -0
  65. data/test/lib/vedeu/models/{attributes/background_test.rb → background_test.rb} +0 -0
  66. data/test/lib/vedeu/models/char_test.rb +46 -0
  67. data/test/lib/vedeu/models/composition_test.rb +7 -0
  68. data/test/lib/vedeu/models/cursor_test.rb +63 -80
  69. data/test/lib/vedeu/models/{attributes/foreground_test.rb → foreground_test.rb} +0 -0
  70. data/test/lib/vedeu/models/geometry_test.rb +8 -10
  71. data/test/lib/vedeu/models/interface_test.rb +26 -21
  72. data/test/lib/vedeu/models/keymap_test.rb +6 -0
  73. data/test/lib/vedeu/models/line_test.rb +82 -3
  74. data/test/lib/vedeu/models/offset_test.rb +121 -0
  75. data/test/lib/vedeu/models/stream_test.rb +107 -8
  76. data/test/lib/vedeu/output/area_test.rb +242 -0
  77. data/test/lib/vedeu/output/compositor_test.rb +12 -3
  78. data/test/lib/vedeu/output/render_test.rb +34 -39
  79. data/test/lib/vedeu/output/viewport_test.rb +36 -0
  80. data/test/lib/vedeu/repositories/cursors_test.rb +32 -9
  81. data/test/lib/vedeu/repositories/focus_test.rb +8 -0
  82. data/test/lib/vedeu/repositories/offsets_test.rb +32 -0
  83. data/test/lib/vedeu/{models/attributes → support}/coercions_test.rb +0 -0
  84. data/test/lib/vedeu/{models/attributes → support}/colour_translator_test.rb +0 -0
  85. data/test/lib/vedeu/support/move_test.rb +35 -0
  86. data/test/lib/vedeu/{models/attributes → support}/presentation_test.rb +0 -0
  87. data/test/lib/vedeu/support/registrar_test.rb +6 -0
  88. data/test/lib/vedeu_test.rb +5 -0
  89. data/vedeu.gemspec +1 -1
  90. metadata +37 -17
@@ -49,7 +49,6 @@ module Vedeu
49
49
  # the styles) and once returned, attempts to set the colours back to the
50
50
  # those of the receiver's parent.
51
51
  #
52
- # @api private
53
52
  # @return [String]
54
53
  def render_colour(&block)
55
54
  [ colour.to_s, yield, parent_colour ].join
@@ -59,7 +58,6 @@ module Vedeu
59
58
  # next model, or finally, the content) and once returned, attempts to set
60
59
  # the colours back to those of the receiver's parent.
61
60
  #
62
- # @api private
63
61
  # @return [String]
64
62
  def render_style(&block)
65
63
  [ style.to_s, yield, parent_style ].join
@@ -67,7 +65,6 @@ module Vedeu
67
65
 
68
66
  # Returns the parent colour as an escape sequence if set.
69
67
  #
70
- # @api private
71
68
  # @return [String]
72
69
  def parent_colour
73
70
  return '' if parent.nil?
@@ -76,7 +73,7 @@ module Vedeu
76
73
  end
77
74
 
78
75
  # Returns the parent style as an escape sequence if set.
79
- # @api private
76
+ #
80
77
  # @return [String]
81
78
  def parent_style
82
79
  return '' if parent.nil?
@@ -6,8 +6,6 @@ module Vedeu
6
6
  # @api private
7
7
  class Registrar
8
8
 
9
- include Common
10
-
11
9
  # @param attributes [Hash]
12
10
  # @return [TrueClass|]
13
11
  def self.record(attributes = {})
@@ -26,6 +24,8 @@ module Vedeu
26
24
  def record
27
25
  Vedeu::Buffers.add(attributes)
28
26
 
27
+ Vedeu::Offsets.add(attributes)
28
+
29
29
  Vedeu::Interfaces.add(attributes)
30
30
 
31
31
  Vedeu::Cursors.add(attributes)
@@ -1,5 +1,6 @@
1
1
  module Vedeu
2
2
 
3
+ # @api private
3
4
  module Repository
4
5
 
5
6
  # Return the whole repository.
@@ -17,6 +18,20 @@ module Vedeu
17
18
  storage.fetch(name) { not_found(name) }
18
19
  end
19
20
 
21
+ # Find entity by named interface, registers an entity by interface name if
22
+ # not found.
23
+ #
24
+ # @param name [String]
25
+ # @return [Cursor|Offset]
26
+ def find_or_create(name)
27
+ storage.fetch(name) do
28
+ Vedeu.log("Entity (#{entity.to_s}) not found, " \
29
+ "registering new for: '#{name}'")
30
+
31
+ storage.store(name, entity.new({ name: name }))
32
+ end
33
+ end
34
+
20
35
  # Returns a collection of the names of all the registered entities.
21
36
  #
22
37
  # @return [Array]
@@ -41,9 +56,16 @@ module Vedeu
41
56
 
42
57
  private
43
58
 
59
+ # @param method [Symbol]
60
+ # @return [String]
61
+ def action(method)
62
+ return 'Registering' if method == :add
63
+
64
+ 'Updating'
65
+ end
66
+
44
67
  # Access to the storage for this repository.
45
68
  #
46
- # @api private
47
69
  # @return [Hash]
48
70
  def storage
49
71
  @_storage ||= in_memory
@@ -52,7 +74,6 @@ module Vedeu
52
74
  # At present, validates that attributes has a `:name` key that is not nil or
53
75
  # empty.
54
76
  #
55
- # @api private
56
77
  # @param attributes [Hash]
57
78
  # @return [TrueClass|MissingRequired]
58
79
  def validate_attributes!(attributes)
@@ -37,7 +37,6 @@ module Vedeu
37
37
  # the F-Keys etc, by capturing the entire sequence.
38
38
  #
39
39
  # @return [String]
40
- # :nocov:
41
40
  def input
42
41
  if raw_mode?
43
42
  keys = console.getch
@@ -52,7 +51,6 @@ module Vedeu
52
51
 
53
52
  end
54
53
  end
55
- # :nocov:
56
54
 
57
55
  # Prints the streams to the screen and returns the streams.
58
56
  #
@@ -8,7 +8,6 @@ module Vedeu
8
8
  # @api private
9
9
  class Trace
10
10
 
11
- # :nocov:
12
11
  # @param options [Hash]
13
12
  # @return []
14
13
  def self.call(options = {})
@@ -52,7 +51,6 @@ module Vedeu
52
51
 
53
52
  # Writes the message to the log file.
54
53
  #
55
- # @api private
56
54
  # @param message [String]
57
55
  # @return [Boolean]
58
56
  def log_this(message)
@@ -63,7 +61,6 @@ module Vedeu
63
61
  # traced. Makes the log file extremely noisy, but very useful for hunting
64
62
  # down bugs.
65
63
  #
66
- # @api private
67
64
  # @param binding [Class]
68
65
  # @return [String]
69
66
  def variables(binding)
@@ -84,25 +81,21 @@ module Vedeu
84
81
  entries.join("\n")
85
82
  end
86
83
 
87
- # @api private
88
84
  # @return [String]
89
85
  def watched
90
86
  options[:event]
91
87
  end
92
88
 
93
- # @api private
94
89
  # @return [Boolean]
95
90
  def trace?
96
91
  options[:trace]
97
92
  end
98
93
 
99
- # @api private
100
94
  # @return [Hash]
101
95
  def options
102
96
  defaults.merge!(@options)
103
97
  end
104
98
 
105
- # @api private
106
99
  # @return [Hash]
107
100
  def defaults
108
101
  {
@@ -132,7 +125,6 @@ module Vedeu
132
125
 
133
126
  # Returns the classes to be traced, without exceptions or ignored classes.
134
127
  #
135
- # @api private
136
128
  # @return [Set]
137
129
  def classes
138
130
  @_classes ||= vedeu_classes - vedeu_exceptions - ignored_classes
@@ -155,7 +147,6 @@ module Vedeu
155
147
  def vedeu_exceptions
156
148
  Set.new [
157
149
  'Vedeu::BufferNotFound',
158
- 'Vedeu::CursorNotFound',
159
150
  'Vedeu::GroupNotFound',
160
151
  'Vedeu::InterfaceNotFound',
161
152
  'Vedeu::InvalidSyntax',
@@ -228,8 +219,6 @@ module Vedeu
228
219
  ]
229
220
  end
230
221
 
231
- # :nocov:
232
-
233
222
  end # Trace
234
223
 
235
224
  end # Vedeu
data/lib/vedeu.rb CHANGED
@@ -38,11 +38,11 @@ require 'vedeu/support/trace'
38
38
 
39
39
  require 'vedeu/api/api'
40
40
 
41
- require 'vedeu/models/attributes/coercions'
42
- require 'vedeu/models/attributes/colour_translator'
43
- require 'vedeu/models/attributes/background'
44
- require 'vedeu/models/attributes/foreground'
45
- require 'vedeu/models/attributes/presentation'
41
+ require 'vedeu/support/coercions'
42
+ require 'vedeu/support/colour_translator'
43
+ require 'vedeu/models/background'
44
+ require 'vedeu/models/foreground'
45
+ require 'vedeu/support/presentation'
46
46
  require 'vedeu/models/composition'
47
47
 
48
48
  require 'vedeu/support/repository'
@@ -57,8 +57,10 @@ require 'vedeu/models/style'
57
57
  require 'vedeu/models/interface'
58
58
  require 'vedeu/models/cursor'
59
59
  require 'vedeu/models/keymap'
60
+ require 'vedeu/models/char'
60
61
  require 'vedeu/models/line'
61
62
  require 'vedeu/models/stream'
63
+ require 'vedeu/models/offset'
62
64
 
63
65
  require 'vedeu/repositories/events'
64
66
 
@@ -72,6 +74,7 @@ require 'vedeu/api/menu'
72
74
  require 'vedeu/api/stream'
73
75
 
74
76
  require 'vedeu/support/keymap_validator'
77
+ require 'vedeu/repositories/offsets'
75
78
  require 'vedeu/repositories/menus'
76
79
  require 'vedeu/repositories/keymaps'
77
80
  require 'vedeu/repositories/interfaces'
@@ -83,14 +86,17 @@ require 'vedeu/repositories/cursors'
83
86
 
84
87
  require 'vedeu/support/registrar'
85
88
 
89
+ require 'vedeu/output/area'
86
90
  require 'vedeu/output/clear'
87
91
  require 'vedeu/output/compositor'
88
92
  require 'vedeu/output/refresh'
89
93
  require 'vedeu/output/render'
90
94
  require 'vedeu/output/view'
95
+ require 'vedeu/output/viewport'
91
96
 
92
97
  require 'vedeu/support/grid'
93
98
  require 'vedeu/support/menu'
99
+ require 'vedeu/support/move'
94
100
 
95
101
  require 'vedeu/input/input'
96
102
 
@@ -106,7 +106,7 @@ module Vedeu
106
106
  end
107
107
 
108
108
  describe '.resize' do
109
- it 'triggers the :_clear_, :_refresh_ and :_cursor_refresh_ events' do
109
+ it 'triggers the :_clear_, and :_refresh_ events' do
110
110
  skip
111
111
  end
112
112
  end
@@ -164,11 +164,20 @@ module Vedeu
164
164
  end
165
165
 
166
166
  describe '.views' do
167
- it 'returns the view attributes for a composition (a collection of ' \
168
- 'interfaces)' do
167
+ it 'allows multiple views to be defined at once' do
169
168
  attrs = Vedeu.views do
170
- view 'osmium'
171
- view 'iridium'
169
+ view 'view_1' do
170
+ line do
171
+ text '1. A line of text in view 1.'
172
+ text '2. Another line of text in view 1.'
173
+ end
174
+ end
175
+ view 'view_2' do
176
+ line do
177
+ text '1. A line of text in view 2.'
178
+ text '2. Another line of text in view 2.'
179
+ end
180
+ end
172
181
  end
173
182
  attrs[:interfaces].size.must_equal(2)
174
183
  end
@@ -3,42 +3,25 @@ require 'test_helper'
3
3
  module Vedeu
4
4
  module API
5
5
  describe Composition do
6
+
6
7
  describe '.render' do
7
- it 'directly writes a view buffer to the terminal' do
8
- skip
8
+ it 'raises an exception when a block is not given' do
9
+ proc { Vedeu.render }.must_raise(InvalidSyntax)
9
10
  end
10
11
  end
11
12
 
12
-
13
13
  describe '#view' do
14
+ it 'returns a Hash' do
15
+ Vedeu.view('thulium') do
16
+ # ...
17
+ end.must_be_instance_of(Hash)
18
+ end
19
+
14
20
  it 'allows a single view to be defined' do
15
21
  skip
16
22
  end
17
23
  end
18
24
 
19
- describe '#views' do
20
- it 'allows multiple views to be defined at once' do
21
- attrs = Vedeu.views do
22
- view 'view_1' do
23
- line do
24
- text '1. A line of text in view 1.'
25
- text '2. Another line of text in view 1.'
26
- end
27
- end
28
- view 'view_2' do
29
- line do
30
- text '1. A line of text in view 2.'
31
- text '2. Another line of text in view 2.'
32
- end
33
- end
34
- end
35
- attrs[:interfaces].size.must_equal(2)
36
- end
37
-
38
- it 'raises an exception when a block is not given' do
39
- proc { Vedeu.views }.must_raise(InvalidSyntax)
40
- end
41
- end
42
25
  end
43
26
  end
44
27
  end
@@ -52,7 +52,7 @@ module Vedeu
52
52
  end.must_be_instance_of(API::Keymap)
53
53
  end
54
54
 
55
- it 'returnsa collection of the interfaces' do
55
+ it 'returns a collection of the interfaces' do
56
56
  Keymap.new.interface('americium').must_equal(['americium'])
57
57
  end
58
58
  end
@@ -65,5 +65,11 @@ module Vedeu
65
65
  end
66
66
  end
67
67
 
68
+ describe '#method_missing' do
69
+ it 'returns nil' do
70
+ Menu.new.some_missing_method(:test).must_equal(nil)
71
+ end
72
+ end
73
+
68
74
  end
69
75
  end
@@ -4,6 +4,10 @@ module Vedeu
4
4
  module API
5
5
  describe Stream do
6
6
  describe '#align' do
7
+ it 'returns a Symbol' do
8
+ Stream.new.align(:left).must_be_instance_of(Symbol)
9
+ end
10
+
7
11
  it 'returns the value assigned' do
8
12
  Stream.new.align(:left).must_equal(:left)
9
13
  end
@@ -17,6 +21,34 @@ module Vedeu
17
21
  end
18
22
  end
19
23
 
24
+ describe '#background' do
25
+ it 'returns a Hash' do
26
+ Stream.new.background('#00ff00').must_be_instance_of(Hash)
27
+ end
28
+
29
+ it 'returns the value assigned' do
30
+ Stream.new.background('#00ff00').must_equal({ background: '#00ff00' })
31
+ end
32
+
33
+ it 'raises an exception if the value is not defined' do
34
+ proc { Stream.new.background('') }.must_raise(InvalidSyntax)
35
+ end
36
+ end
37
+
38
+ describe '#foreground' do
39
+ it 'returns a Hash' do
40
+ Stream.new.foreground('#00ff00').must_be_instance_of(Hash)
41
+ end
42
+
43
+ it 'returns the value assigned' do
44
+ Stream.new.foreground('#00ff00').must_equal({ foreground: '#00ff00' })
45
+ end
46
+
47
+ it 'raises an exception if the value is not defined' do
48
+ proc { Stream.new.foreground('') }.must_raise(InvalidSyntax)
49
+ end
50
+ end
51
+
20
52
  describe '#left' do
21
53
  it 'returns a Symbol' do
22
54
  Stream.new.left.must_equal(:left)
@@ -0,0 +1,46 @@
1
+ require 'test_helper'
2
+
3
+ module Vedeu
4
+ describe Char do
5
+ let(:instance) { Char.new(attributes) }
6
+ let(:attributes) {
7
+ {
8
+ colour: { foreground: '#ffff00', background: '#0000ff' },
9
+ parent: {
10
+ colour: {
11
+ foreground: '#00ff00',
12
+ background: '#ff00ff'
13
+ },
14
+ style: []
15
+ },
16
+ style: [],
17
+ value: value,
18
+ }
19
+ }
20
+ let(:value) { 'a' }
21
+
22
+ describe '#initialize' do
23
+ it 'returns a new instance of Char' do
24
+ instance.must_be_instance_of(Char)
25
+ end
26
+ end
27
+
28
+ describe '#to_s' do
29
+ it 'returns a String' do
30
+ instance.to_s.must_be_instance_of(String)
31
+ end
32
+
33
+ it 'returns the escape sequences and content' do
34
+ # - char colours and style as set in Stream#chars.
35
+ # - the value.
36
+ # - the colours and style of the line which the Char belongs to.
37
+ instance.to_s.must_equal(
38
+ "\e[38;2;255;255;0m\e[48;2;0;0;255m" \
39
+ "a" \
40
+ "\e[38;2;0;255;0m\e[48;2;255;0;255m"
41
+ )
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -4,6 +4,7 @@ require 'json'
4
4
 
5
5
  module Vedeu
6
6
  describe Composition do
7
+
7
8
  before { Buffers.reset }
8
9
 
9
10
  describe '#initialize' do
@@ -33,5 +34,11 @@ module Vedeu
33
34
  end
34
35
  end
35
36
 
37
+ describe '#method_missing' do
38
+ it 'returns nil' do
39
+ Composition.new.some_missing_method(:test).must_equal(nil)
40
+ end
41
+ end
42
+
36
43
  end
37
44
  end
@@ -4,21 +4,22 @@ module Vedeu
4
4
  describe Cursor do
5
5
  let(:attributes) {
6
6
  {
7
- name: 'silver',
8
- state: :show,
9
- x: 12,
10
- y: 5,
7
+ name: 'silver',
8
+ state: :show,
9
+ x: 19,
10
+ y: 8
11
11
  }
12
12
  }
13
13
 
14
14
  before do
15
15
  Interfaces.reset
16
16
  Vedeu.interface 'silver' do
17
- width 10
17
+ y 5
18
18
  height 4
19
19
  x 12
20
- y 5
20
+ width 10
21
21
  end
22
+ Terminal.console.stubs(:print)
22
23
  end
23
24
 
24
25
  describe '#initialize' do
@@ -30,82 +31,78 @@ module Vedeu
30
31
  describe '#attributes' do
31
32
  it 'returns a hash containing the attributes of the instance' do
32
33
  Cursor.new(attributes).attributes.must_equal(
33
- { name: 'silver', state: :show, x: 12, y: 5 }
34
+ { name: 'silver', state: :show, x: 19, y: 8 }
34
35
  )
35
36
  end
36
37
  end
37
38
 
38
- describe '#move_up' do
39
- it 'does not move up when already at the top' do
40
- cursor = Cursor.new(attributes)
41
- cursor.move_up
42
- cursor.attributes.must_equal(
43
- { name: 'silver', state: :show, x: 12, y: 5 }
44
- )
39
+ describe '#x' do
40
+ it 'returns a Fixnum' do
41
+ Cursor.new(attributes).x.must_be_instance_of(Fixnum)
45
42
  end
46
43
 
47
- it 'moves the cursor up' do
48
- cursor = Cursor.new(attributes)
49
- 3.times { cursor.move_down }
50
- cursor.move_up
51
- cursor.attributes.must_equal(
52
- { name: 'silver', state: :show, x: 12, y: 7 }
53
- )
44
+ context 'when the cursors position is outside the interface' do
45
+ let(:attributes) { { name: 'silver', state: :show, x: 10, y: 8 } }
46
+
47
+ it 'repositions the cursor at the start of the line' do
48
+ Cursor.new(attributes).attributes.must_equal(
49
+ { name: 'silver', state: :show, x: 12, y: 8 }
50
+ )
51
+ end
52
+ end
53
+
54
+ context 'when the cursors position is outside the interface' do
55
+ let(:attributes) { { name: 'silver', state: :show, x: 25, y: 8 } }
56
+
57
+ it 'repositions the cursor at the end of the line' do
58
+ Cursor.new(attributes).attributes.must_equal(
59
+ { name: 'silver', state: :show, x: 21, y: 8 }
60
+ )
61
+ end
54
62
  end
55
63
  end
56
64
 
57
- describe '#move_down' do
58
- it 'moves the cursor down' do
59
- cursor = Cursor.new(attributes)
60
- cursor.move_down
61
- cursor.attributes.must_equal(
62
- { name: 'silver', state: :show, x: 12, y: 6 }
63
- )
65
+ describe '#y' do
66
+ it 'returns a Fixnum' do
67
+ Cursor.new(attributes).y.must_be_instance_of(Fixnum)
64
68
  end
65
69
 
66
- it 'does not move down when already at the bottom' do
67
- cursor = Cursor.new(attributes)
68
- 5.times { cursor.move_down }
69
- cursor.attributes.must_equal(
70
- { name: 'silver', state: :show, x: 12, y: 8 }
71
- )
70
+ context 'when the cursors position is outside the interface' do
71
+ let(:attributes) { { name: 'silver', state: :show, x: 19, y: 3 } }
72
+
73
+ it 'repositions the cursor at the start of the line' do
74
+ Cursor.new(attributes).attributes.must_equal(
75
+ { name: 'silver', state: :show, x: 19, y: 5 }
76
+ )
77
+ end
72
78
  end
73
- end
74
79
 
75
- describe '#move_left' do
76
- it 'does not move left when already at leftmost' do
77
- cursor = Cursor.new(attributes)
78
- cursor.move_left
79
- cursor.attributes.must_equal(
80
- { name: 'silver', state: :show, x: 12, y: 5 }
81
- )
80
+ context 'when the cursors position is outside the interface' do
81
+ let(:attributes) { { name: 'silver', state: :show, x: 19, y: 12 } }
82
+
83
+ it 'repositions the cursor at the end of the line' do
84
+ Cursor.new(attributes).attributes.must_equal(
85
+ { name: 'silver', state: :show, x: 19, y: 8 }
86
+ )
87
+ end
82
88
  end
89
+ end
83
90
 
84
- it 'moves the cursor left' do
85
- cursor = Cursor.new(attributes)
86
- 3.times { cursor.move_right }
87
- cursor.move_left
88
- cursor.attributes.must_equal(
89
- { name: 'silver', state: :show, x: 14, y: 5 }
91
+ describe '#refresh' do
92
+ it 'returns a hash containing the attributes of the instance' do
93
+ Cursor.new(attributes).refresh.must_equal(
94
+ { name: 'silver', state: :show, x: 19, y: 8 }
90
95
  )
91
96
  end
92
97
  end
93
98
 
94
- describe '#move_right' do
95
- it 'does not move right when already at rightmost' do
96
- cursor = Cursor.new(attributes)
97
- 11.times { cursor.move_right }
98
- cursor.attributes.must_equal(
99
- { name: 'silver', state: :show, x: 21, y: 5 }
100
- )
99
+ describe '#visible?' do
100
+ it 'returns false when the cursor is not visible' do
101
+ Cursor.new({ state: :hide }).visible?.must_equal(false)
101
102
  end
102
103
 
103
- it 'moves the cursor right' do
104
- cursor = Cursor.new(attributes)
105
- cursor.move_right
106
- cursor.attributes.must_equal(
107
- { name: 'silver', state: :show, x: 13, y: 5 }
108
- )
104
+ it 'returns true when the cursor is visible' do
105
+ Cursor.new({ state: :show }).visible?.must_equal(true)
109
106
  end
110
107
  end
111
108
 
@@ -114,11 +111,11 @@ module Vedeu
114
111
  cursor = Cursor.new(attributes)
115
112
  cursor.hide
116
113
  cursor.attributes.must_equal(
117
- { name: 'silver', state: :hide, x: 12, y: 5 }
114
+ { name: 'silver', state: :hide, x: 19, y: 8 }
118
115
  )
119
116
  cursor.show
120
117
  cursor.attributes.must_equal(
121
- { name: 'silver', state: :show, x: 12, y: 5 }
118
+ { name: 'silver', state: :show, x: 19, y: 8 }
122
119
  )
123
120
  end
124
121
  end
@@ -128,21 +125,7 @@ module Vedeu
128
125
  cursor = Cursor.new(attributes)
129
126
  cursor.hide
130
127
  cursor.attributes.must_equal(
131
- { name: 'silver', state: :hide, x: 12, y: 5 }
132
- )
133
- end
134
- end
135
-
136
- describe '#toggle' do
137
- it 'sets the visibility to the opposite of its current state' do
138
- cursor = Cursor.new(attributes)
139
- cursor.toggle
140
- cursor.attributes.must_equal(
141
- { name: 'silver', state: :hide, x: 12, y: 5 }
142
- )
143
- cursor.toggle
144
- cursor.attributes.must_equal(
145
- { name: 'silver', state: :show, x: 12, y: 5 }
128
+ { name: 'silver', state: :hide, x: 19, y: 8 }
146
129
  )
147
130
  end
148
131
  end
@@ -150,14 +133,14 @@ module Vedeu
150
133
  describe '#to_s' do
151
134
  it 'returns the escape sequence to position and set the visibility of ' \
152
135
  'the cursor' do
153
- Cursor.new(attributes).to_s.must_equal("\e[5;12H\e[?25h")
136
+ Cursor.new(attributes).to_s.must_equal("\e[8;19H\e[?25h")
154
137
  end
155
138
 
156
139
  it 'returns the escape sequence to position and set the visibility of ' \
157
140
  'the cursor and returns to that position after yielding the block' do
158
141
  Cursor.new(attributes).to_s do
159
142
  # ...
160
- end.must_equal("\e[5;12H\e[?25h\e[5;12H\e[?25h")
143
+ end.must_equal("\e[8;19H\e[?25h\e[8;19H\e[?25h")
161
144
  end
162
145
  end
163
146
  end