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
@@ -1,57 +0,0 @@
|
|
1
|
-
module Vedeu
|
2
|
-
class NotImplementedError < StandardError; end
|
3
|
-
|
4
|
-
class Interface
|
5
|
-
def initialize(options = {})
|
6
|
-
@options = options
|
7
|
-
@output = []
|
8
|
-
end
|
9
|
-
|
10
|
-
def initial_state
|
11
|
-
raise NotImplementedError, 'Subclasses implement this method.'
|
12
|
-
end
|
13
|
-
|
14
|
-
def input
|
15
|
-
raise Collapse if evaluate == :stop
|
16
|
-
end
|
17
|
-
|
18
|
-
def output
|
19
|
-
write
|
20
|
-
end
|
21
|
-
|
22
|
-
def geometry
|
23
|
-
@geometry ||= Geometry.new(options[:geometry])
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
attr_reader :options
|
29
|
-
|
30
|
-
def evaluate
|
31
|
-
@output = Commands.execute(read)
|
32
|
-
end
|
33
|
-
|
34
|
-
def read
|
35
|
-
Terminal.input
|
36
|
-
end
|
37
|
-
|
38
|
-
def write
|
39
|
-
Compositor.arrange(@output, self)
|
40
|
-
end
|
41
|
-
|
42
|
-
def options
|
43
|
-
defaults.merge!(@options)
|
44
|
-
end
|
45
|
-
|
46
|
-
def defaults
|
47
|
-
{
|
48
|
-
geometry: {
|
49
|
-
y: 1,
|
50
|
-
x: 1,
|
51
|
-
width: :auto,
|
52
|
-
height: :auto
|
53
|
-
}
|
54
|
-
}
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module Vedeu
|
2
|
-
class UndefinedInterface < StandardError; end
|
3
|
-
|
4
|
-
module Interfaces
|
5
|
-
extend self
|
6
|
-
attr_accessor :interfaces
|
7
|
-
|
8
|
-
def define(&block)
|
9
|
-
if block_given?
|
10
|
-
yield self
|
11
|
-
else
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def defined
|
17
|
-
interfaces.empty? ? default : self
|
18
|
-
end
|
19
|
-
|
20
|
-
def list
|
21
|
-
interfaces.inspect
|
22
|
-
end
|
23
|
-
|
24
|
-
def add(name, options = {}, klass = DummyInterface)
|
25
|
-
interfaces[name] = klass.new(options) if valid?(klass)
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
|
-
def reset
|
30
|
-
@interfaces = {}
|
31
|
-
end
|
32
|
-
|
33
|
-
def find(name)
|
34
|
-
interfaces[name] || nil
|
35
|
-
end
|
36
|
-
|
37
|
-
def initial_state
|
38
|
-
interfaces.values.map { |io| io.initial_state }
|
39
|
-
end
|
40
|
-
|
41
|
-
def input
|
42
|
-
interfaces.values.map { |io| io.input }
|
43
|
-
end
|
44
|
-
|
45
|
-
def output
|
46
|
-
interfaces.values.map { |io| io.output }
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def valid?(klass)
|
52
|
-
raise UndefinedInterface unless Object.const_defined?(klass.to_s)
|
53
|
-
true
|
54
|
-
end
|
55
|
-
|
56
|
-
def default
|
57
|
-
add(:dummy)
|
58
|
-
|
59
|
-
self
|
60
|
-
end
|
61
|
-
|
62
|
-
def interfaces
|
63
|
-
@interfaces ||= {}
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Vedeu
|
2
|
-
class InvalidCommand < StandardError; end
|
3
|
-
|
4
|
-
class Command
|
5
|
-
class << self
|
6
|
-
def define(name, klass, args = [], options = {})
|
7
|
-
new(name, klass, args, options).define
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(name, klass, args = [], options = {})
|
12
|
-
@name, @klass, @args, @options = name, klass, args, options
|
13
|
-
end
|
14
|
-
|
15
|
-
def define
|
16
|
-
{ name => executable } if valid?
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
attr_reader :name, :klass, :args, :options
|
22
|
-
|
23
|
-
def executable
|
24
|
-
Proc.new { klass.dispatch(*args) }
|
25
|
-
end
|
26
|
-
|
27
|
-
def valid?
|
28
|
-
empty_name? || empty_klass? || klass_defined? || dispatch_defined? || true
|
29
|
-
end
|
30
|
-
|
31
|
-
def empty_name?
|
32
|
-
raise InvalidCommand, "Command name is missing." if name.to_s.empty?
|
33
|
-
end
|
34
|
-
|
35
|
-
def empty_klass?
|
36
|
-
raise InvalidCommand, "Command class is missing." if klass.to_s.empty?
|
37
|
-
end
|
38
|
-
|
39
|
-
def klass_defined?
|
40
|
-
unless Object.const_defined?(klass.to_s)
|
41
|
-
raise InvalidCommand, "Command class is not defined."
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def dispatch_defined?
|
46
|
-
unless klass.singleton_methods(false).include?(:dispatch)
|
47
|
-
raise InvalidCommand, "Command dispatch method is not defined."
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Vedeu
|
2
|
-
module Commands
|
3
|
-
extend self
|
4
|
-
|
5
|
-
def define(&block)
|
6
|
-
if block_given?
|
7
|
-
yield self
|
8
|
-
else
|
9
|
-
self
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def execute(command = "")
|
14
|
-
commands.fetch(command).call if exists?(command)
|
15
|
-
end
|
16
|
-
|
17
|
-
def list
|
18
|
-
commands.inspect
|
19
|
-
end
|
20
|
-
|
21
|
-
def add(name, klass, args = [], options = {})
|
22
|
-
commands.merge!(Command.define(name, klass, args, options))
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def exists?(command)
|
28
|
-
commands.fetch(command, false)
|
29
|
-
end
|
30
|
-
|
31
|
-
def commands
|
32
|
-
@commands ||= { "exit" => Proc.new { Exit.dispatch } }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require_relative '../../../test_helper'
|
2
|
-
|
3
|
-
module Vedeu
|
4
|
-
describe DummyInterface do
|
5
|
-
let(:described_class) { DummyInterface }
|
6
|
-
let(:described_instance) { described_class.new }
|
7
|
-
|
8
|
-
describe '#initial_state' do
|
9
|
-
let(:subject) { described_instance.initial_state }
|
10
|
-
|
11
|
-
it { subject.must_be_instance_of(NilClass) }
|
12
|
-
end
|
13
|
-
|
14
|
-
describe '#input' do
|
15
|
-
let(:subject) { described_instance.input }
|
16
|
-
end
|
17
|
-
|
18
|
-
describe '#output' do
|
19
|
-
let(:subject) { described_instance.output }
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require_relative '../../../test_helper'
|
2
|
-
|
3
|
-
module Vedeu
|
4
|
-
describe Interface do
|
5
|
-
let(:described_class) { Interface }
|
6
|
-
let(:described_instance) { described_class.new(options) }
|
7
|
-
let(:options) { {} }
|
8
|
-
|
9
|
-
it { described_instance.must_be_instance_of(Interface) }
|
10
|
-
|
11
|
-
describe '#initial_state' do
|
12
|
-
let(:subject) { described_instance.initial_state }
|
13
|
-
|
14
|
-
it { proc { subject }.must_raise(NotImplementedError) }
|
15
|
-
end
|
16
|
-
|
17
|
-
describe '#input' do
|
18
|
-
let(:subject) { described_instance.input }
|
19
|
-
|
20
|
-
before do
|
21
|
-
Terminal.stubs(:input).returns('stop')
|
22
|
-
Commands.stubs(:execute)
|
23
|
-
end
|
24
|
-
|
25
|
-
it { subject.must_be_instance_of(NilClass) }
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '#output' do
|
29
|
-
let(:subject) { described_instance.output }
|
30
|
-
let(:command) { mock }
|
31
|
-
|
32
|
-
before { Compositor.stubs(:arrange).returns([]) }
|
33
|
-
|
34
|
-
it 'sends the output of the command to the compositor' do
|
35
|
-
subject.must_be_instance_of(Array)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '#geometry' do
|
40
|
-
let(:subject) { described_instance.geometry }
|
41
|
-
|
42
|
-
it { subject.must_be_instance_of(Geometry) }
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,108 +0,0 @@
|
|
1
|
-
require_relative '../../../test_helper'
|
2
|
-
|
3
|
-
module Vedeu
|
4
|
-
describe Interfaces do
|
5
|
-
let(:described_class) { Interfaces }
|
6
|
-
|
7
|
-
describe '.define' do
|
8
|
-
let(:subject) { described_class.define }
|
9
|
-
|
10
|
-
it { subject.must_be_instance_of(Module) }
|
11
|
-
|
12
|
-
context 'when a block is given' do
|
13
|
-
let(:subject) { described_class.define { :some_block } }
|
14
|
-
|
15
|
-
it { subject.must_be_instance_of(Symbol) }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe '.defined' do
|
20
|
-
let(:subject) { described_class.defined }
|
21
|
-
|
22
|
-
after { described_class.interfaces = {} }
|
23
|
-
|
24
|
-
context 'when interfaces are not defined' do
|
25
|
-
before { described_class.interfaces = {} }
|
26
|
-
|
27
|
-
it 'adds the default interface and returns all interfaces' do
|
28
|
-
subject.must_be_instance_of(Module)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context 'when interfaces are defined' do
|
33
|
-
before { described_class.interfaces = { mock: :interface } }
|
34
|
-
|
35
|
-
it { subject.must_be_instance_of(Module) }
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '.list' do
|
40
|
-
let(:subject) { described_class.list }
|
41
|
-
|
42
|
-
it { subject.must_be_instance_of(String) }
|
43
|
-
end
|
44
|
-
|
45
|
-
describe '.add' do
|
46
|
-
let(:subject) { described_class.add(interface, options, klass) }
|
47
|
-
let(:interface) {}
|
48
|
-
let(:klass) { DummyInterface }
|
49
|
-
let(:options) { {} }
|
50
|
-
|
51
|
-
it { subject.must_be_instance_of(Module) }
|
52
|
-
|
53
|
-
context 'when the interface class does not exist' do
|
54
|
-
before { Object.stubs(:const_defined?).returns(false) }
|
55
|
-
|
56
|
-
it { proc { subject }.must_raise(UndefinedInterface) }
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe '.reset' do
|
61
|
-
let(:subject) { described_class.reset }
|
62
|
-
let(:interface) { :dummy }
|
63
|
-
|
64
|
-
before { described_class.add(:dummy) }
|
65
|
-
|
66
|
-
it { subject.must_be_instance_of(Hash) }
|
67
|
-
|
68
|
-
it { subject.must_be_empty }
|
69
|
-
end
|
70
|
-
|
71
|
-
describe '.find' do
|
72
|
-
let(:subject) { described_class.find(interface) }
|
73
|
-
let(:interface) { :dummy }
|
74
|
-
|
75
|
-
context 'when the interface exists' do
|
76
|
-
before { described_class.add(:dummy) }
|
77
|
-
|
78
|
-
it { subject.must_be_instance_of(DummyInterface) }
|
79
|
-
end
|
80
|
-
|
81
|
-
context 'when the interface does not exist' do
|
82
|
-
before { described_class.reset }
|
83
|
-
|
84
|
-
it { subject.must_be_instance_of(NilClass) }
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe '.initial_state' do
|
89
|
-
let(:subject) { described_class.initial_state }
|
90
|
-
|
91
|
-
it { subject.must_be_instance_of(Array) }
|
92
|
-
end
|
93
|
-
|
94
|
-
describe '.input' do
|
95
|
-
let(:subject) { described_class.input }
|
96
|
-
|
97
|
-
before { Terminal.stubs(:input).returns("some input") }
|
98
|
-
|
99
|
-
it { subject.must_be_instance_of(Array) }
|
100
|
-
end
|
101
|
-
|
102
|
-
describe '.output' do
|
103
|
-
let(:subject) { described_class.output }
|
104
|
-
|
105
|
-
it { subject.must_be_instance_of(Array) }
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
require_relative '../../../test_helper'
|
2
|
-
|
3
|
-
module Vedeu
|
4
|
-
describe Command do
|
5
|
-
let(:described_class) { Command }
|
6
|
-
let(:described_instance) { described_class.new(cmd_name, cmd_klass, cmd_args, cmd_options) }
|
7
|
-
let(:cmd_name) { "dummy" }
|
8
|
-
let(:cmd_klass) { DummyCommand }
|
9
|
-
let(:cmd_args) { [] }
|
10
|
-
let(:cmd_options) { {} }
|
11
|
-
|
12
|
-
it { described_instance.must_be_instance_of(Command) }
|
13
|
-
|
14
|
-
describe '#define' do
|
15
|
-
subject do
|
16
|
-
described_class.define(cmd_name, cmd_klass, cmd_args, cmd_options)
|
17
|
-
end
|
18
|
-
|
19
|
-
it { subject.must_be_instance_of(Hash) }
|
20
|
-
|
21
|
-
it { subject.wont_be_empty }
|
22
|
-
|
23
|
-
context "when the command name is empty" do
|
24
|
-
let(:cmd_name) { "" }
|
25
|
-
|
26
|
-
it { proc { subject }.must_raise(InvalidCommand) }
|
27
|
-
end
|
28
|
-
|
29
|
-
context "when the command class is empty" do
|
30
|
-
let(:cmd_klass) { "" }
|
31
|
-
|
32
|
-
it { proc { subject }.must_raise(InvalidCommand) }
|
33
|
-
end
|
34
|
-
|
35
|
-
context "when the command class is not defined" do
|
36
|
-
before { Object.stubs(:const_defined?).returns(false) }
|
37
|
-
|
38
|
-
it { proc { subject }.must_raise(InvalidCommand) }
|
39
|
-
end
|
40
|
-
|
41
|
-
context "when the command class doesn't have a .dispatch method" do
|
42
|
-
before { cmd_klass.stubs(:singleton_methods).returns([]) }
|
43
|
-
|
44
|
-
it { proc { subject }.must_raise(InvalidCommand) }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|