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.
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,7 +1,7 @@
1
1
  module Vedeu
2
2
  class DummyCommand
3
- def self.dispatch
4
- 'Dummy'
3
+ def self.dispatch(value = :dummy)
4
+ value
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,4 @@
1
+ module Vedeu
2
+ class DummyInterface
3
+ end
4
+ end
@@ -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.reset)
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, :show)
111
+ options.fetch(:cursor)
113
112
  end
114
113
 
115
114
  def mode
116
- options.fetch(:mode, :cooked)
115
+ options.fetch(:mode)
117
116
  end
118
117
 
119
118
  def clear_screen?
120
- options.fetch(:clear, true)
119
+ return options.fetch(:clear)
121
120
  end
122
121
 
123
122
  def noop
data/lib/vedeu/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vedeu
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.11"
3
3
  end
@@ -13,7 +13,7 @@ module Vedeu
13
13
 
14
14
  before do
15
15
  Terminal.stubs(:open).yields(self)
16
- Interfaces.stubs(:initial_state)
16
+ InterfaceRepository.stubs(:initial_state)
17
17
  EventLoop.stubs(:main_sequence)
18
18
  Terminal.stubs(:close)
19
19
  end
@@ -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
- Interfaces.defined
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...']] }
@@ -29,7 +29,7 @@ module Vedeu
29
29
  context 'when the position is set' do
30
30
  let(:position) { [4, 5] }
31
31
 
32
- it { subject.must_equal("\e[5;6H") }
32
+ it { subject.must_equal("\e[4;5H") }
33
33
  end
34
34
 
35
35
  context 'when the colour is not set' do
@@ -24,7 +24,7 @@ module Vedeu
24
24
  let(:x) { 19 }
25
25
 
26
26
  it 'returns a position escape sequence' do
27
- subject.must_equal("\e[13;20H")
27
+ subject.must_equal("\e[12;19H")
28
28
  end
29
29
  end
30
30
  end
@@ -7,9 +7,8 @@ module Vedeu
7
7
  let(:subject) { described_class.new }
8
8
 
9
9
  before do
10
- Interfaces.stubs(:defined).returns(defined)
11
- defined.stubs(:input).returns("stop")
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