vedeu 0.0.10 → 0.0.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.
- checksums.yaml +4 -4
- data/README.md +21 -2
- data/Rakefile +8 -0
- data/bin/vedeu +1 -1
- data/config/cucumber.yml +8 -0
- data/features/getting_started.feature +10 -0
- data/features/step_definitions/vedeu_steps.rb +11 -0
- data/features/support/env.rb +12 -0
- data/lib/vedeu.rb +30 -9
- data/lib/vedeu/application.rb +1 -1
- data/lib/vedeu/launcher.rb +26 -0
- data/lib/vedeu/output/colour.rb +1 -1
- data/lib/vedeu/output/compositor.rb +9 -6
- data/lib/vedeu/output/directive.rb +1 -1
- data/lib/vedeu/output/geometry.rb +1 -1
- data/lib/vedeu/output/position.rb +2 -2
- data/lib/vedeu/output/style.rb +1 -1
- data/lib/vedeu/output/wordwrap.rb +2 -1
- data/lib/vedeu/process/event_loop.rb +2 -2
- data/lib/vedeu/process/input.rb +30 -0
- data/lib/vedeu/repository/command.rb +32 -0
- data/lib/vedeu/repository/command_repository.rb +27 -0
- data/lib/vedeu/{process → repository}/dummy_command.rb +2 -2
- data/lib/vedeu/repository/dummy_interface.rb +4 -0
- data/lib/vedeu/repository/interface.rb +52 -0
- data/lib/vedeu/repository/interface_repository.rb +49 -0
- data/lib/vedeu/repository/repository.rb +35 -0
- data/lib/vedeu/repository/storage.rb +46 -0
- data/lib/vedeu/support/terminal.rb +5 -6
- data/lib/vedeu/version.rb +1 -1
- data/test/lib/vedeu/application_test.rb +1 -1
- data/test/lib/vedeu/output/compositor_test.rb +15 -13
- data/test/lib/vedeu/output/directive_test.rb +1 -1
- data/test/lib/vedeu/output/position_test.rb +1 -1
- data/test/lib/vedeu/process/event_loop_test.rb +2 -3
- data/test/lib/vedeu/process/input_test.rb +19 -0
- data/test/lib/vedeu/repository/command_repository_test.rb +55 -0
- data/test/lib/vedeu/repository/command_test.rb +39 -0
- data/test/lib/vedeu/repository/interface_repository_test.rb +71 -0
- data/test/lib/vedeu/repository/interface_test.rb +65 -0
- data/test/lib/vedeu/repository/repository_test.rb +88 -0
- data/test/lib/vedeu/repository/storage_test.rb +50 -0
- data/test/test_helper.rb +8 -0
- data/vedeu.gemspec +3 -0
- metadata +75 -21
- data/lib/vedeu/interface/dummy_interface.rb +0 -14
- data/lib/vedeu/interface/interface.rb +0 -57
- data/lib/vedeu/interface/interfaces.rb +0 -66
- data/lib/vedeu/process/command.rb +0 -51
- data/lib/vedeu/process/commands.rb +0 -35
- data/test/lib/vedeu/interface/dummy_test.rb +0 -22
- data/test/lib/vedeu/interface/interface_test.rb +0 -45
- data/test/lib/vedeu/interface/interfaces_test.rb +0 -108
- data/test/lib/vedeu/process/command_test.rb +0 -48
- data/test/lib/vedeu/process/commands_test.rb +0 -56
- data/test/lib/vedeu/process/dummy_command_test.rb +0 -16
@@ -0,0 +1,52 @@
|
|
1
|
+
module Vedeu
|
2
|
+
class Interface
|
3
|
+
attr_accessor :id, :active, :attributes, :result, :name, :geometry
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def create(attributes = {})
|
7
|
+
new(attributes).create
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(attributes = {})
|
12
|
+
@attributes = attributes || {}
|
13
|
+
@name = attributes[:name]
|
14
|
+
@active = false
|
15
|
+
@geometry = Geometry.new(attributes[:geometry])
|
16
|
+
end
|
17
|
+
|
18
|
+
def create
|
19
|
+
InterfaceRepository.create(self)
|
20
|
+
|
21
|
+
InterfaceRepository.activate(self.name)
|
22
|
+
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def origin(index = 0)
|
27
|
+
Position.set(geometry.vy(index), geometry.vx)
|
28
|
+
end
|
29
|
+
|
30
|
+
def initial_state
|
31
|
+
# raise NotImplementedError, 'Subclasses implement this method.'
|
32
|
+
end
|
33
|
+
|
34
|
+
def input
|
35
|
+
raise Collapse if evaluate == :stop
|
36
|
+
end
|
37
|
+
|
38
|
+
def output
|
39
|
+
Compositor.arrange(@result, self) unless @result.nil? || @result.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def evaluate
|
45
|
+
@result = Input.evaluate(read)
|
46
|
+
end
|
47
|
+
|
48
|
+
def read
|
49
|
+
Terminal.input
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Vedeu
|
2
|
+
class InterfaceRepository
|
3
|
+
extend Repository
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def activate(name)
|
7
|
+
deactivate
|
8
|
+
|
9
|
+
all.map do |interface|
|
10
|
+
interface.active = true if interface.name == name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def deactivate
|
15
|
+
all.map { |interface| interface.active = false }
|
16
|
+
end
|
17
|
+
|
18
|
+
def activated
|
19
|
+
query(klass, :active, true)
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_by_name(value)
|
23
|
+
query(klass, :name, value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def initial_state
|
27
|
+
all.map { |interface| interface.initial_state }
|
28
|
+
end
|
29
|
+
|
30
|
+
def update; end
|
31
|
+
|
32
|
+
def input
|
33
|
+
all.map do |interface|
|
34
|
+
interface.origin
|
35
|
+
|
36
|
+
interface.input
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def output
|
41
|
+
all.map { |interface| interface.output }
|
42
|
+
end
|
43
|
+
|
44
|
+
def klass
|
45
|
+
Interface
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Vedeu
|
2
|
+
module Repository
|
3
|
+
def adaptor
|
4
|
+
@adaptor ||= Storage.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def adaptor=(adaptor)
|
8
|
+
@adaptor = adaptor
|
9
|
+
end
|
10
|
+
|
11
|
+
def find(id)
|
12
|
+
adaptor.find(self.klass, id)
|
13
|
+
end
|
14
|
+
|
15
|
+
def all
|
16
|
+
adaptor.all(self.klass)
|
17
|
+
end
|
18
|
+
|
19
|
+
def query(klass, attribute, value)
|
20
|
+
adaptor.query(klass, attribute, value)
|
21
|
+
end
|
22
|
+
|
23
|
+
def create(model)
|
24
|
+
adaptor.create(model)
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(model)
|
28
|
+
adaptor.delete(model)
|
29
|
+
end
|
30
|
+
|
31
|
+
def reset
|
32
|
+
adaptor.reset(self.klass)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Vedeu
|
2
|
+
class Storage
|
3
|
+
def initialize
|
4
|
+
@counter = 0
|
5
|
+
@map = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def create(record)
|
9
|
+
@counter = @counter + 1
|
10
|
+
record.id ||= @counter
|
11
|
+
map_for(record)[record.id] = record
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete(record)
|
15
|
+
map_for(record).delete(record.id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset(klass)
|
19
|
+
all(klass).map { |record| delete(record) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def find(klass, id)
|
23
|
+
map_for_class(klass).fetch(id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def all(klass)
|
27
|
+
map_for_class(klass).values
|
28
|
+
end
|
29
|
+
|
30
|
+
def query(klass, attribute, value)
|
31
|
+
map_for_class(klass).select do |id, result|
|
32
|
+
return result if result.send(attribute) == value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def map_for_class(klass)
|
39
|
+
@map[klass.to_s.to_sym] ||= {}
|
40
|
+
end
|
41
|
+
|
42
|
+
def map_for(record)
|
43
|
+
map_for_class(record.class)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -26,9 +26,8 @@ module Vedeu
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def close
|
29
|
-
clear_screen
|
30
29
|
show_cursor
|
31
|
-
output(Position.
|
30
|
+
output(Position.set(height - 1, 1))
|
32
31
|
end
|
33
32
|
|
34
33
|
def cooked(instance, &block)
|
@@ -73,7 +72,7 @@ module Vedeu
|
|
73
72
|
end
|
74
73
|
|
75
74
|
def initialize(options = {}, &block)
|
76
|
-
@options = options
|
75
|
+
@options = options || {}
|
77
76
|
|
78
77
|
yield self if block_given?
|
79
78
|
end
|
@@ -109,15 +108,15 @@ module Vedeu
|
|
109
108
|
end
|
110
109
|
|
111
110
|
def cursor
|
112
|
-
options.fetch(:cursor
|
111
|
+
options.fetch(:cursor)
|
113
112
|
end
|
114
113
|
|
115
114
|
def mode
|
116
|
-
options.fetch(:mode
|
115
|
+
options.fetch(:mode)
|
117
116
|
end
|
118
117
|
|
119
118
|
def clear_screen?
|
120
|
-
options.fetch(:clear
|
119
|
+
return options.fetch(:clear)
|
121
120
|
end
|
122
121
|
|
123
122
|
def noop
|
data/lib/vedeu/version.rb
CHANGED
@@ -5,21 +5,11 @@ module Vedeu
|
|
5
5
|
let(:described_class) { Compositor }
|
6
6
|
let(:described_instance) { described_class.new(output) }
|
7
7
|
let(:output) { [[]] }
|
8
|
-
let(:stream) {}
|
9
|
-
let(:interface) {
|
10
|
-
Vedeu::Interface.new({
|
11
|
-
geometry: {
|
12
|
-
y: 2,
|
13
|
-
x: 2,
|
14
|
-
width: 20,
|
15
|
-
height: 10
|
16
|
-
}
|
17
|
-
})
|
18
|
-
}
|
8
|
+
let(:stream) { [] }
|
9
|
+
let(:interface) { 'dummy' }
|
19
10
|
|
20
11
|
before do
|
21
|
-
|
22
|
-
Terminal.stubs(:output)
|
12
|
+
@interface = Interface.create({ name: 'dummy' })
|
23
13
|
Renderer.stubs(:write).returns(stream)
|
24
14
|
end
|
25
15
|
|
@@ -34,6 +24,18 @@ module Vedeu
|
|
34
24
|
it { subject.must_be_instance_of(NilClass) }
|
35
25
|
end
|
36
26
|
|
27
|
+
context 'when an array (single interface)' do
|
28
|
+
let(:output) { [[]] }
|
29
|
+
|
30
|
+
it { subject.must_be_instance_of(Array) }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when a hash (multiple interfaces)' do
|
34
|
+
let(:output) { { test_interface: [] } }
|
35
|
+
|
36
|
+
it { subject.must_be_instance_of(Array) }
|
37
|
+
end
|
38
|
+
|
37
39
|
context 'when unstyled' do
|
38
40
|
context 'and a single line' do
|
39
41
|
let(:output) { [['Some text...']] }
|
@@ -7,9 +7,8 @@ module Vedeu
|
|
7
7
|
let(:subject) { described_class.new }
|
8
8
|
|
9
9
|
before do
|
10
|
-
|
11
|
-
|
12
|
-
defined.stubs(:output).returns(NilClass)
|
10
|
+
InterfaceRepository.stubs(:input).returns("stop")
|
11
|
+
InterfaceRepository.stubs(:output).returns(NilClass)
|
13
12
|
end
|
14
13
|
|
15
14
|
it { subject.must_be_instance_of(EventLoop) }
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
module Vedeu
|
4
|
+
describe Input do
|
5
|
+
let(:described_class) { Input }
|
6
|
+
let(:input) { "" }
|
7
|
+
let(:args) { [] }
|
8
|
+
|
9
|
+
before do
|
10
|
+
CommandRepository.stubs(:find_by_input)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '.evaluate' do
|
14
|
+
let(:subject) { described_class.evaluate(input, args) }
|
15
|
+
|
16
|
+
it { subject.must_be_instance_of(NilClass) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
module Vedeu
|
4
|
+
describe CommandRepository do
|
5
|
+
let(:described_class) { CommandRepository }
|
6
|
+
let(:input) { }
|
7
|
+
|
8
|
+
before do
|
9
|
+
Command.create({ name: 'apple',
|
10
|
+
klass: DummyCommand,
|
11
|
+
options: { keypress: 'a', keyword: 'apple' } })
|
12
|
+
Command.create({ name: 'banana',
|
13
|
+
klass: DummyCommand,
|
14
|
+
options: { keypress: 'b', keyword: 'banana' } })
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
CommandRepository.reset
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.find_by_input' do
|
22
|
+
let(:subject) { described_class.find_by_input(input) }
|
23
|
+
|
24
|
+
context 'when the command was found by keypress' do
|
25
|
+
let(:input) { 'b' }
|
26
|
+
|
27
|
+
it { subject.must_be_instance_of(Command) }
|
28
|
+
|
29
|
+
it { subject.name.must_equal('banana') }
|
30
|
+
|
31
|
+
it { subject.name.wont_equal('apple') }
|
32
|
+
|
33
|
+
it { subject.keypress.must_equal('b') }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when the command was found by keyword' do
|
37
|
+
let(:input) { 'apple' }
|
38
|
+
|
39
|
+
it { subject.must_be_instance_of(Command) }
|
40
|
+
|
41
|
+
it { subject.keypress.must_equal('a') }
|
42
|
+
|
43
|
+
it { subject.keypress.wont_equal('b') }
|
44
|
+
|
45
|
+
it { subject.name.wont_equal('banana') }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '.klass' do
|
50
|
+
let(:subject) { described_class.klass }
|
51
|
+
|
52
|
+
it { subject.must_equal(Command) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../../../test_helper'
|
2
|
+
|
3
|
+
module Vedeu
|
4
|
+
class DummyCommand
|
5
|
+
def self.dispatch; end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Command do
|
9
|
+
let(:described_class) { Command }
|
10
|
+
let(:described_instance) { described_class.new(attributes) }
|
11
|
+
let(:attributes) { { name: :test_command } }
|
12
|
+
|
13
|
+
it { described_instance.must_be_instance_of(Command) }
|
14
|
+
|
15
|
+
describe '#create' do
|
16
|
+
let(:subject) { described_class.create(attributes) }
|
17
|
+
|
18
|
+
it { subject.must_be_instance_of(Command) }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#execute' do
|
22
|
+
let(:subject) { described_class.execute(args) }
|
23
|
+
|
24
|
+
it { skip }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#executable' do
|
28
|
+
let(:subject) { described_instance.executable }
|
29
|
+
|
30
|
+
it { skip }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#execute' do
|
34
|
+
let(:subject) { described_instance.execute }
|
35
|
+
|
36
|
+
it { skip }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|