vedeu 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -2
  3. data/Rakefile +8 -0
  4. data/bin/vedeu +1 -1
  5. data/config/cucumber.yml +8 -0
  6. data/features/getting_started.feature +10 -0
  7. data/features/step_definitions/vedeu_steps.rb +11 -0
  8. data/features/support/env.rb +12 -0
  9. data/lib/vedeu.rb +30 -9
  10. data/lib/vedeu/application.rb +1 -1
  11. data/lib/vedeu/launcher.rb +26 -0
  12. data/lib/vedeu/output/colour.rb +1 -1
  13. data/lib/vedeu/output/compositor.rb +9 -6
  14. data/lib/vedeu/output/directive.rb +1 -1
  15. data/lib/vedeu/output/geometry.rb +1 -1
  16. data/lib/vedeu/output/position.rb +2 -2
  17. data/lib/vedeu/output/style.rb +1 -1
  18. data/lib/vedeu/output/wordwrap.rb +2 -1
  19. data/lib/vedeu/process/event_loop.rb +2 -2
  20. data/lib/vedeu/process/input.rb +30 -0
  21. data/lib/vedeu/repository/command.rb +32 -0
  22. data/lib/vedeu/repository/command_repository.rb +27 -0
  23. data/lib/vedeu/{process → repository}/dummy_command.rb +2 -2
  24. data/lib/vedeu/repository/dummy_interface.rb +4 -0
  25. data/lib/vedeu/repository/interface.rb +52 -0
  26. data/lib/vedeu/repository/interface_repository.rb +49 -0
  27. data/lib/vedeu/repository/repository.rb +35 -0
  28. data/lib/vedeu/repository/storage.rb +46 -0
  29. data/lib/vedeu/support/terminal.rb +5 -6
  30. data/lib/vedeu/version.rb +1 -1
  31. data/test/lib/vedeu/application_test.rb +1 -1
  32. data/test/lib/vedeu/output/compositor_test.rb +15 -13
  33. data/test/lib/vedeu/output/directive_test.rb +1 -1
  34. data/test/lib/vedeu/output/position_test.rb +1 -1
  35. data/test/lib/vedeu/process/event_loop_test.rb +2 -3
  36. data/test/lib/vedeu/process/input_test.rb +19 -0
  37. data/test/lib/vedeu/repository/command_repository_test.rb +55 -0
  38. data/test/lib/vedeu/repository/command_test.rb +39 -0
  39. data/test/lib/vedeu/repository/interface_repository_test.rb +71 -0
  40. data/test/lib/vedeu/repository/interface_test.rb +65 -0
  41. data/test/lib/vedeu/repository/repository_test.rb +88 -0
  42. data/test/lib/vedeu/repository/storage_test.rb +50 -0
  43. data/test/test_helper.rb +8 -0
  44. data/vedeu.gemspec +3 -0
  45. metadata +75 -21
  46. data/lib/vedeu/interface/dummy_interface.rb +0 -14
  47. data/lib/vedeu/interface/interface.rb +0 -57
  48. data/lib/vedeu/interface/interfaces.rb +0 -66
  49. data/lib/vedeu/process/command.rb +0 -51
  50. data/lib/vedeu/process/commands.rb +0 -35
  51. data/test/lib/vedeu/interface/dummy_test.rb +0 -22
  52. data/test/lib/vedeu/interface/interface_test.rb +0 -45
  53. data/test/lib/vedeu/interface/interfaces_test.rb +0 -108
  54. data/test/lib/vedeu/process/command_test.rb +0 -48
  55. data/test/lib/vedeu/process/commands_test.rb +0 -56
  56. data/test/lib/vedeu/process/dummy_command_test.rb +0 -16
@@ -1,14 +0,0 @@
1
- module Vedeu
2
- class DummyInterface < Interface
3
- def initial_state
4
- end
5
-
6
- def input
7
- super
8
- end
9
-
10
- def output
11
- super
12
- end
13
- end
14
- end
@@ -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