vedeu 0.2.10 → 0.2.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/docs/events.md +6 -0
- data/examples/{cursor_app/cursor_app.rb → cursor_app.rb} +1 -1
- data/examples/{lines_app/lines_app.rb → lines_app.rb} +1 -1
- data/lib/vedeu.rb +48 -28
- data/lib/vedeu/api/api.rb +8 -95
- data/lib/vedeu/application.rb +6 -2
- data/lib/vedeu/{models → colours}/background.rb +1 -1
- data/lib/vedeu/{models → colours}/colour.rb +0 -0
- data/lib/vedeu/{models → colours}/foreground.rb +2 -2
- data/lib/vedeu/{support/colour_translator.rb → colours/translator.rb} +7 -7
- data/lib/vedeu/input/input.rb +13 -5
- data/lib/vedeu/models/geometry.rb +30 -2
- data/lib/vedeu/models/key.rb +39 -0
- data/lib/vedeu/output/compositor.rb +30 -76
- data/lib/vedeu/output/output.rb +74 -0
- data/lib/vedeu/output/viewport.rb +36 -44
- data/lib/vedeu/repositories/buffers.rb +5 -18
- data/lib/vedeu/repositories/cursors.rb +16 -8
- data/lib/vedeu/repositories/events.rb +96 -9
- data/lib/vedeu/repositories/focus.rb +21 -20
- data/lib/vedeu/repositories/groups.rb +3 -11
- data/lib/vedeu/repositories/interfaces.rb +6 -9
- data/lib/vedeu/repositories/keymaps.rb +8 -3
- data/lib/vedeu/repositories/menus.rb +6 -21
- data/lib/vedeu/{models → repositories/models}/buffer.rb +62 -28
- data/lib/vedeu/{models → repositories/models}/cursor.rb +8 -2
- data/lib/vedeu/{models → repositories/models}/event.rb +7 -0
- data/lib/vedeu/repositories/models/group.rb +56 -0
- data/lib/vedeu/{models → repositories/models}/interface.rb +6 -0
- data/lib/vedeu/{models → repositories/models}/keymap.rb +7 -1
- data/lib/vedeu/{models → repositories/models}/menu.rb +9 -0
- data/lib/vedeu/{models → repositories/models}/offset.rb +8 -1
- data/lib/vedeu/repositories/offsets.rb +17 -12
- data/lib/vedeu/support/bounding_area.rb +127 -0
- data/lib/vedeu/support/common.rb +8 -0
- data/lib/vedeu/support/exceptions.rb +2 -12
- data/lib/vedeu/support/model.rb +14 -0
- data/lib/vedeu/support/refresh.rb +8 -7
- data/lib/vedeu/support/registrar.rb +7 -1
- data/lib/vedeu/support/repository.rb +31 -10
- data/lib/vedeu/support/sentence.rb +67 -0
- data/lib/vedeu/support/terminal.rb +19 -0
- data/lib/vedeu/support/trace.rb +2 -5
- data/test/integration/api/api_test.rb +97 -0
- data/test/integration/api_dsl/dsl_api_test.rb +4 -0
- data/test/integration/api_dsl/dsl_composition_test.rb +4 -0
- data/test/integration/api_dsl/dsl_defined_test.rb +4 -0
- data/test/integration/api_dsl/dsl_helpers_test.rb +4 -0
- data/test/integration/api_dsl/dsl_interface_test.rb +4 -0
- data/test/integration/api_dsl/dsl_keymap.rb +4 -0
- data/test/integration/api_dsl/dsl_line_test.rb +4 -0
- data/test/integration/api_dsl/dsl_menu_test.rb +4 -0
- data/test/integration/api_dsl/dsl_stream_test.rb +138 -0
- data/test/lib/vedeu/api/api_test.rb +1 -25
- data/test/lib/vedeu/api/helpers_test.rb +0 -10
- data/test/lib/vedeu/{models → colours}/background_test.rb +0 -0
- data/test/lib/vedeu/{models → colours}/colour_test.rb +0 -0
- data/test/lib/vedeu/{models → colours}/foreground_test.rb +0 -0
- data/test/lib/vedeu/{support/colour_translator_test.rb → colours/translator_test.rb} +3 -3
- data/test/lib/vedeu/input/input_test.rb +16 -47
- data/test/lib/vedeu/models/geometry_test.rb +46 -0
- data/test/lib/vedeu/models/group_test.rb +99 -0
- data/test/lib/vedeu/models/key_test.rb +41 -0
- data/test/lib/vedeu/output/compositor_test.rb +25 -101
- data/test/lib/vedeu/output/output_test.rb +108 -0
- data/test/lib/vedeu/repositories/buffers_test.rb +0 -8
- data/test/lib/vedeu/repositories/cursors_test.rb +34 -0
- data/test/lib/vedeu/repositories/focus_test.rb +37 -28
- data/test/lib/vedeu/repositories/interfaces_test.rb +1 -1
- data/test/lib/vedeu/repositories/keymaps_test.rb +6 -20
- data/test/lib/vedeu/repositories/menus_test.rb +0 -6
- data/test/lib/vedeu/{models → repositories/models}/buffer_test.rb +24 -27
- data/test/lib/vedeu/{models → repositories/models}/cursor_test.rb +0 -0
- data/test/lib/vedeu/{models → repositories/models}/event_test.rb +0 -0
- data/test/lib/vedeu/{models → repositories/models}/interface_test.rb +0 -0
- data/test/lib/vedeu/{models → repositories/models}/keymap_test.rb +0 -0
- data/test/lib/vedeu/{models → repositories/models}/menu_test.rb +0 -0
- data/test/lib/vedeu/{models → repositories/models}/offset_test.rb +0 -0
- data/test/lib/vedeu/support/bounding_area_test.rb +139 -0
- data/test/lib/vedeu/support/coercions_test.rb +6 -17
- data/test/lib/vedeu/support/grid_test.rb +1 -1
- data/test/lib/vedeu/support/model_test.rb +23 -0
- data/test/lib/vedeu/support/presentation_test.rb +0 -10
- data/test/lib/vedeu/support/refresh_test.rb +2 -2
- data/test/lib/vedeu/support/repository_test.rb +63 -64
- data/test/lib/vedeu/support/sentence_test.rb +48 -0
- data/test/lib/vedeu/support/terminal_test.rb +86 -6
- data/test/support/test_classes/all.rb +5 -0
- data/test/support/test_classes/coercions.rb +16 -0
- data/test/support/test_classes/helpers.rb +19 -0
- data/test/support/test_classes/model.rb +23 -0
- data/test/support/test_classes/presentation.rb +16 -0
- data/test/support/test_classes/repositories.rb +26 -0
- data/test/support/test_modules/all.rb +1 -0
- data/test/support/test_modules/repository.rb +16 -0
- data/test/test_helper.rb +4 -0
- data/vedeu.gemspec +3 -3
- metadata +95 -50
- data/lib/vedeu/output/clear.rb +0 -88
- data/lib/vedeu/output/render.rb +0 -50
- data/lib/vedeu/repositories/positional.rb +0 -23
- data/test/lib/vedeu/output/clear_test.rb +0 -56
- data/test/lib/vedeu/output/render_test.rb +0 -100
- data/test/lib/vedeu/repositories/positional_test.rb +0 -50
data/lib/vedeu/output/clear.rb
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
module Vedeu
|
2
|
-
|
3
|
-
# Clears all the character data for the area defined by an interface. This
|
4
|
-
# class is called every time an interface is rendered to prepare the area
|
5
|
-
# for new data.
|
6
|
-
#
|
7
|
-
# @note We don't simply clear the entire terminal as this would remove the
|
8
|
-
# content of other interfaces which are being displayed.
|
9
|
-
#
|
10
|
-
# @todo What if an interface 'moves' or changes shape due to the terminal
|
11
|
-
# resizing?
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
class Clear
|
15
|
-
|
16
|
-
# Blanks the area defined by the interface.
|
17
|
-
#
|
18
|
-
# @param interface [Interface]
|
19
|
-
# @param options [Hash]
|
20
|
-
# @return [String]
|
21
|
-
# @see #initialize
|
22
|
-
def self.call(interface, options = {})
|
23
|
-
new(interface, options).clear
|
24
|
-
end
|
25
|
-
|
26
|
-
# Returns a new instance of Clear.
|
27
|
-
#
|
28
|
-
# @param interface [Interface]
|
29
|
-
# @param options [Hash]
|
30
|
-
# @option options :direct [Boolean] Send escape sequences to clear an area
|
31
|
-
# directly to the Terminal.
|
32
|
-
# @return [Clear]
|
33
|
-
def initialize(interface, options = {})
|
34
|
-
@interface = interface
|
35
|
-
@options = defaults.merge!(options)
|
36
|
-
end
|
37
|
-
|
38
|
-
# Send the cleared area to the terminal.
|
39
|
-
#
|
40
|
-
# @return [Array]
|
41
|
-
def clear
|
42
|
-
return Terminal.output(view) if direct?
|
43
|
-
|
44
|
-
view
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
attr_reader :interface, :options
|
50
|
-
|
51
|
-
# For each visible line of the interface, set the foreground and background
|
52
|
-
# colours to those specified when the interface was defined, then starting
|
53
|
-
# write space characters over the area which the interface occupies.
|
54
|
-
#
|
55
|
-
# @return [String]
|
56
|
-
def view
|
57
|
-
Vedeu.log("Clearing view: '#{interface.name}'")
|
58
|
-
|
59
|
-
rows.inject([colours]) do |line, index|
|
60
|
-
line << interface.origin(index) { ' ' * interface.width }
|
61
|
-
end.join
|
62
|
-
end
|
63
|
-
|
64
|
-
# @return [String]
|
65
|
-
def colours
|
66
|
-
interface.colour.to_s
|
67
|
-
end
|
68
|
-
|
69
|
-
# @return [Enumerator]
|
70
|
-
def rows
|
71
|
-
interface.height.times
|
72
|
-
end
|
73
|
-
|
74
|
-
# @return [Boolean]
|
75
|
-
def direct?
|
76
|
-
options[:direct]
|
77
|
-
end
|
78
|
-
|
79
|
-
# @return [Hash]
|
80
|
-
def defaults
|
81
|
-
{
|
82
|
-
direct: true
|
83
|
-
}
|
84
|
-
end
|
85
|
-
|
86
|
-
end # Clear
|
87
|
-
|
88
|
-
end # Vedeu
|
data/lib/vedeu/output/render.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module Vedeu
|
2
|
-
|
3
|
-
# Attempts to convert the provided interface object with associated lines,
|
4
|
-
# streams, colours, styles, etc, into a single string containing all content
|
5
|
-
# and escape sequences.
|
6
|
-
#
|
7
|
-
# @api private
|
8
|
-
class Render
|
9
|
-
|
10
|
-
# Create a new instance of Render with the provided {Vedeu::Interface} and
|
11
|
-
# then convert the interface into a single string of content and escape
|
12
|
-
# sequences.
|
13
|
-
#
|
14
|
-
# @param interface [Interface]
|
15
|
-
# @return [String]
|
16
|
-
def self.call(interface)
|
17
|
-
new(interface).render
|
18
|
-
end
|
19
|
-
|
20
|
-
# Return a new instance of Render.
|
21
|
-
#
|
22
|
-
# @param interface [Interface]
|
23
|
-
# @return [Render]
|
24
|
-
def initialize(interface)
|
25
|
-
@interface = interface
|
26
|
-
end
|
27
|
-
|
28
|
-
# Produces a single string which contains all content and escape sequences
|
29
|
-
# required to render this interface to a position in the terminal window.
|
30
|
-
#
|
31
|
-
# @return [String]
|
32
|
-
def render
|
33
|
-
out = [ Clear.call(interface, { direct: false }) ]
|
34
|
-
|
35
|
-
Vedeu.log("Rendering view: '#{interface.name}'")
|
36
|
-
|
37
|
-
interface.viewport.each_with_index do |line, index|
|
38
|
-
out << interface.origin(index)
|
39
|
-
out << line.join
|
40
|
-
end
|
41
|
-
out.join
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
attr_reader :interface
|
47
|
-
|
48
|
-
end # Render
|
49
|
-
|
50
|
-
end # Vedeu
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Vedeu
|
2
|
-
|
3
|
-
# Repository helper module which reduces duplication in Offsets and Cursors.
|
4
|
-
#
|
5
|
-
module Positional
|
6
|
-
|
7
|
-
# Add or update the offset or cursor coordinates.
|
8
|
-
#
|
9
|
-
# @param attributes [Hash]
|
10
|
-
# @return [Offset]
|
11
|
-
def add(attributes)
|
12
|
-
validate_attributes!(attributes)
|
13
|
-
|
14
|
-
Vedeu.log("#{action(__callee__)} positional (#{entity}): " \
|
15
|
-
"'#{attributes[:name]}'")
|
16
|
-
|
17
|
-
storage.store(attributes[:name], entity.new(attributes))
|
18
|
-
end
|
19
|
-
alias_method :update, :add
|
20
|
-
|
21
|
-
end # Positional
|
22
|
-
|
23
|
-
end # Vedeu
|
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module Vedeu
|
4
|
-
|
5
|
-
describe Clear do
|
6
|
-
|
7
|
-
before do
|
8
|
-
Interfaces.reset
|
9
|
-
Terminal.console.stubs(:print)
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#initialize' do
|
13
|
-
it 'returns an instance of itself' do
|
14
|
-
interface = mock('Interface')
|
15
|
-
Clear.new(interface).must_be_instance_of(Clear)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe '.call' do
|
20
|
-
it 'returns the escape sequence to clear the whole interface' do
|
21
|
-
interface = Interface.new({
|
22
|
-
name: 'Clear.call',
|
23
|
-
geometry: {
|
24
|
-
width: 5,
|
25
|
-
height: 2
|
26
|
-
}
|
27
|
-
})
|
28
|
-
Clear.call(interface).must_equal([
|
29
|
-
"\e[1;1H \e[1;1H" \
|
30
|
-
"\e[2;1H \e[2;1H"
|
31
|
-
])
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'returns the escape sequence to clear the whole interface with specified colours' do
|
35
|
-
interface = Interface.new({
|
36
|
-
name: 'Clear.call',
|
37
|
-
geometry: {
|
38
|
-
width: 5,
|
39
|
-
height: 2,
|
40
|
-
},
|
41
|
-
colour: {
|
42
|
-
foreground: '#00ff00',
|
43
|
-
background: '#ffff00'
|
44
|
-
}
|
45
|
-
})
|
46
|
-
Clear.call(interface).must_equal([
|
47
|
-
"\e[38;2;0;255;0m\e[48;2;255;255;0m" \
|
48
|
-
"\e[1;1H \e[1;1H" \
|
49
|
-
"\e[2;1H \e[2;1H"
|
50
|
-
])
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
end # Clear
|
55
|
-
|
56
|
-
end # Vedeu
|
@@ -1,100 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module Vedeu
|
4
|
-
|
5
|
-
describe Render do
|
6
|
-
|
7
|
-
before do
|
8
|
-
Terminal.console.stubs(:print)
|
9
|
-
|
10
|
-
Buffers.reset
|
11
|
-
Cursors.reset
|
12
|
-
Interfaces.reset
|
13
|
-
|
14
|
-
Vedeu.interface('fluorine') do
|
15
|
-
width 32
|
16
|
-
height 3
|
17
|
-
line 'this is the first'
|
18
|
-
line 'this is the second and it is long'
|
19
|
-
line 'this is the third, it is even longer and still truncated'
|
20
|
-
line 'this should not render'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '#initialize' do
|
25
|
-
it 'returns an instance of itself' do
|
26
|
-
interface = Interface.new
|
27
|
-
Render.new(interface).must_be_instance_of(Render)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe '.call' do
|
32
|
-
let(:interface) { Vedeu.use('fluorine') }
|
33
|
-
|
34
|
-
before { interface.stubs(:in_focus?).returns(true) }
|
35
|
-
|
36
|
-
it 'returns the content for the interface' do
|
37
|
-
Render.call(interface).must_equal(
|
38
|
-
"\e[1;1H \e[1;1H" \
|
39
|
-
"\e[2;1H \e[2;1H" \
|
40
|
-
"\e[3;1H \e[3;1H" \
|
41
|
-
"\e[1;1Hthis is the first" \
|
42
|
-
"\e[2;1Hthis is the second and it is lon" \
|
43
|
-
"\e[3;1Hthis is the third, it is even lo"
|
44
|
-
)
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'returns a blank interface if there are no streams of text' do
|
48
|
-
interface = Interface.new({
|
49
|
-
name: 'fluorine',
|
50
|
-
geometry: {
|
51
|
-
width: 32,
|
52
|
-
height: 3,
|
53
|
-
},
|
54
|
-
lines: []
|
55
|
-
})
|
56
|
-
|
57
|
-
Render.call(interface).must_equal(
|
58
|
-
"\e[1;1H \e[1;1H" \
|
59
|
-
"\e[2;1H \e[2;1H" \
|
60
|
-
"\e[3;1H \e[3;1H"
|
61
|
-
)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'skips lines which have streams with no content' do
|
65
|
-
interface = Interface.new({
|
66
|
-
name: 'fluorine',
|
67
|
-
geometry: {
|
68
|
-
width: 32,
|
69
|
-
height: 3,
|
70
|
-
},
|
71
|
-
lines: [
|
72
|
-
{
|
73
|
-
streams: [{ text: 'this is the first' }]
|
74
|
-
}, {
|
75
|
-
streams: { text: '' }
|
76
|
-
}, {
|
77
|
-
streams: [
|
78
|
-
{ text: 'this is the third, ' },
|
79
|
-
{ text: 'it is even longer ' },
|
80
|
-
{ text: 'and still truncated' }
|
81
|
-
]
|
82
|
-
}, {
|
83
|
-
streams: [{ text: 'this should not render' }]
|
84
|
-
}
|
85
|
-
]
|
86
|
-
})
|
87
|
-
Render.call(interface).must_equal(
|
88
|
-
"\e[1;1H \e[1;1H" \
|
89
|
-
"\e[2;1H \e[2;1H" \
|
90
|
-
"\e[3;1H \e[3;1H" \
|
91
|
-
"\e[1;1Hthis is the first" \
|
92
|
-
"\e[2;1H" \
|
93
|
-
"\e[3;1Hthis is the third, it is even lo"
|
94
|
-
)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
end # Render
|
99
|
-
|
100
|
-
end # Vedeu
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
module Vedeu
|
4
|
-
|
5
|
-
describe Positional do
|
6
|
-
|
7
|
-
before do
|
8
|
-
Offsets.reset
|
9
|
-
Cursors.reset
|
10
|
-
Registrar.record({ name: 'chromium' })
|
11
|
-
end
|
12
|
-
|
13
|
-
describe '#add' do
|
14
|
-
it 'raises an exception if a :name attribute is not provided' do
|
15
|
-
proc { Offsets.add({ no_name: 'no_name' }) }
|
16
|
-
.must_raise(MissingRequired)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'returns a new instance of Offset once stored' do
|
20
|
-
Offsets.add({ name: 'praseodymium' }).must_be_instance_of(Offset)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '#add' do
|
25
|
-
let(:attributes) { { name: 'chromium' } }
|
26
|
-
|
27
|
-
it 'returns a new Cursor after registering' do
|
28
|
-
Cursors.add(attributes).must_be_instance_of(Cursor)
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'returns a new Cursor after updating' do
|
32
|
-
Cursors.update(attributes).must_be_instance_of(Cursor)
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'when the attributes do not have the :name key' do
|
36
|
-
let(:attributes) { { no_name_key: 'some_value' } }
|
37
|
-
|
38
|
-
it 'raises an exception' do
|
39
|
-
proc { Cursors.update(attributes) }.must_raise(MissingRequired)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'raises an exception' do
|
43
|
-
proc { Cursors.add(attributes) }.must_raise(MissingRequired)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
end # Positional
|
49
|
-
|
50
|
-
end # Vedeu
|