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,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