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