vedeu 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Guardfile +1 -1
  4. data/README.md +14 -0
  5. data/lib/vedeu.rb +1 -0
  6. data/lib/vedeu/interface/dummy.rb +13 -0
  7. data/lib/vedeu/interface/interface.rb +1 -1
  8. data/lib/vedeu/interface/interfaces.rb +10 -9
  9. data/lib/vedeu/output/colour.rb +2 -0
  10. data/lib/vedeu/output/compositor.rb +3 -23
  11. data/lib/vedeu/output/directive.rb +27 -14
  12. data/lib/vedeu/output/geometry.rb +6 -1
  13. data/lib/vedeu/output/position.rb +8 -3
  14. data/lib/vedeu/output/wordwrap.rb +84 -0
  15. data/lib/vedeu/version.rb +1 -1
  16. data/test/lib/vedeu/application_test.rb +15 -5
  17. data/test/lib/vedeu/interface/dummy_test.rb +5 -5
  18. data/test/lib/vedeu/interface/interface_test.rb +17 -7
  19. data/test/lib/vedeu/interface/interfaces_test.rb +29 -20
  20. data/test/lib/vedeu/output/background_test.rb +40 -3
  21. data/test/lib/vedeu/output/base_test.rb +2 -4
  22. data/test/lib/vedeu/output/colour_test.rb +6 -6
  23. data/test/lib/vedeu/output/compositor_test.rb +15 -15
  24. data/test/lib/vedeu/output/directive_test.rb +36 -35
  25. data/test/lib/vedeu/output/esc_test.rb +9 -9
  26. data/test/lib/vedeu/output/foreground_test.rb +39 -2
  27. data/test/lib/vedeu/output/geometry_test.rb +51 -7
  28. data/test/lib/vedeu/output/position_test.rb +15 -6
  29. data/test/lib/vedeu/output/renderer_test.rb +19 -1
  30. data/test/lib/vedeu/output/style_test.rb +1 -2
  31. data/test/lib/vedeu/output/wordwrap_test.rb +59 -0
  32. data/test/lib/vedeu/process/command_test.rb +8 -8
  33. data/test/lib/vedeu/process/commands_test.rb +27 -7
  34. data/test/lib/vedeu/process/exit_test.rb +1 -1
  35. data/test/lib/vedeu/support/terminal_test.rb +27 -24
  36. data/test/test_helper.rb +1 -1
  37. data/vedeu.gemspec +5 -5
  38. metadata +21 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f49a2565aad7f4e16195f4669892ace8f6d0f8c7
4
- data.tar.gz: 04ddcf49ad7df1af4681bfbf0109af0f0da54037
3
+ metadata.gz: f52154b63c5d3fdf54cecda5b7937e995c505901
4
+ data.tar.gz: 65d02119eee86d923a1ab265260767ae2e475743
5
5
  SHA512:
6
- metadata.gz: b6712ac5a5121704148d9afeb3a8ed7655e4b523f5b71f2d8d4fd477f4feff62b45ab61a598de0064491fc682698e9cc94a53587bf0c2f6ed16f633e07bb9914
7
- data.tar.gz: 8bb9e432e9178e755b68771d51f3fbfcdd8a1eba33b4bf6ed4794dfbebb6c38a97ea44a031b12dd514902e255aef82972fc3b0b5f37706297fd42ccd26f845ae
6
+ metadata.gz: 77cab7109821b024cb2ffd7bfe4d705a6df42ced0b17f0c3805b9e183516ac0070bd5ed85eb3e5899ffdf83ea7d2eb054b6472a222b5afb2ac3f70c3edb82b47
7
+ data.tar.gz: fc489cc11f1671cfd6efff9df4d0b333c46da375f93f4bb3f9073f7ac5d45d5818008911d61c13907ef06df0b10fd4f6216a256e7cf48912f39aac1afec0f7ad
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.1.1
1
+ ruby-2.1.2
data/Guardfile CHANGED
@@ -1,4 +1,4 @@
1
- guard :minitest, all_after_pass: true do
1
+ guard :minitest, all_after_pass: true, env: { 'no_simplecov' => true } do
2
2
  watch(%r{^test/(.*)_test\.rb})
3
3
  watch(%r{^lib/(.+)\.rb}) do |m|
4
4
  "test/lib/#{m[1]}_test.rb"
data/README.md CHANGED
@@ -72,6 +72,20 @@ TODO: Write detailed documentation
72
72
  When we create the interface we define it's width, height, and origin (y, x).
73
73
  These numbers are based on the area available to the terminal. If the terminal is 80x25, then our interface can use all or some of this area.
74
74
 
75
+ ### On Composition
76
+
77
+ [ # interface
78
+ [ # stream
79
+ [ # directive
80
+ 34, 22 # position directive
81
+ :red, :black # colour directive
82
+ ],
83
+
84
+ :directive, # style directive
85
+
86
+ "Textual content..." # stream data
87
+ ]
88
+ ]
75
89
 
76
90
  ## Contributing
77
91
 
data/lib/vedeu.rb CHANGED
@@ -14,6 +14,7 @@ require_relative 'vedeu/output/position'
14
14
  require_relative 'vedeu/output/renderer'
15
15
  require_relative 'vedeu/output/style'
16
16
  require_relative 'vedeu/output/translator'
17
+ require_relative 'vedeu/output/wordwrap'
17
18
 
18
19
  require_relative 'vedeu/interface/interfaces'
19
20
  require_relative 'vedeu/interface/interface'
@@ -5,5 +5,18 @@ module Vedeu
5
5
  # def input; end
6
6
 
7
7
  # def output; end
8
+
9
+ private
10
+
11
+ def options
12
+ {
13
+ geometry: {
14
+ y: 1,
15
+ x: 1,
16
+ width: :auto,
17
+ height: :auto
18
+ }
19
+ }
20
+ end
8
21
  end
9
22
  end
@@ -25,7 +25,7 @@ module Vedeu
25
25
  end
26
26
 
27
27
  def output(command)
28
- Compositor.write(command, self)
28
+ Compositor.arrange(command, self)
29
29
  end
30
30
 
31
31
  def geometry
@@ -3,14 +3,7 @@ module Vedeu
3
3
 
4
4
  module Interfaces
5
5
  extend self
6
-
7
- def default
8
- add(:dummy, Dummy)
9
- end
10
-
11
- def defined
12
- interfaces.empty? ? nil : interfaces
13
- end
6
+ attr_accessor :interfaces
14
7
 
15
8
  def define(&block)
16
9
  if block_given?
@@ -20,6 +13,14 @@ module Vedeu
20
13
  end
21
14
  end
22
15
 
16
+ def defined
17
+ interfaces.empty? ? nil : self
18
+ end
19
+
20
+ def default
21
+ add(:dummy, Dummy)
22
+ end
23
+
23
24
  def list
24
25
  interfaces.inspect
25
26
  end
@@ -27,7 +28,7 @@ module Vedeu
27
28
  def add(name, klass, options = {})
28
29
  if valid?(klass)
29
30
  interfaces[name] = Proc.new { klass.new(options) }
30
- interfaces
31
+ self
31
32
  end
32
33
  end
33
34
 
@@ -2,6 +2,8 @@ module Vedeu
2
2
  class Colour
3
3
  class << self
4
4
  def define(pair = [])
5
+ return '' if pair.empty?
6
+
5
7
  new(pair).define
6
8
  end
7
9
  alias_method :set, :define
@@ -1,10 +1,10 @@
1
1
  module Vedeu
2
2
  class Compositor
3
3
  class << self
4
- def write(output = [], interface = Dummy)
4
+ def arrange(output = [], interface = Dummy)
5
5
  return if output.nil? || output.empty?
6
6
 
7
- new(output, interface).write
7
+ new(output, interface).arrange
8
8
  end
9
9
  end
10
10
 
@@ -12,7 +12,7 @@ module Vedeu
12
12
  @output, @interface = output, interface
13
13
  end
14
14
 
15
- def write
15
+ def arrange
16
16
  Renderer.write(composition)
17
17
  end
18
18
 
@@ -51,30 +51,10 @@ module Vedeu
51
51
  geometry.vy(index)
52
52
  end
53
53
 
54
- def height
55
- geometry.height
56
- end
57
-
58
54
  def width
59
55
  geometry.width
60
56
  end
61
57
 
62
- def y
63
- geometry.y
64
- end
65
-
66
- def dy
67
- geometry.dy
68
- end
69
-
70
- def x
71
- geometry.x
72
- end
73
-
74
- def dx
75
- geometry.dx
76
- end
77
-
78
58
  def geometry
79
59
  interface.geometry
80
60
  end
@@ -3,32 +3,45 @@ module Vedeu
3
3
 
4
4
  class Directive
5
5
  class << self
6
- def enact(directive)
7
- new(directive).enact
6
+ def enact(directives = {})
7
+ new(directives).enact
8
8
  end
9
9
  end
10
10
 
11
- def initialize(directive)
12
- @directive = directive
11
+ def initialize(directives = {})
12
+ @directives = directives
13
13
  end
14
14
 
15
15
  def enact
16
- raise InvalidDirective unless valid_directive?
16
+ [set_position, set_colour, set_style].join
17
+ end
17
18
 
18
- return Style.set(directive) if directive.is_a?(Symbol)
19
+ private
19
20
 
20
- if directive.is_a?(Array)
21
- return Position.set(*directive) if directive.first.is_a?(Numeric)
22
- return Colour.set(directive) if directive.first.is_a?(Symbol)
23
- end
21
+ attr_reader :directives
22
+
23
+ def set_position
24
+ Position.set(*position)
24
25
  end
25
26
 
26
- private
27
+ def set_colour
28
+ Colour.set(colour)
29
+ end
27
30
 
28
- attr_reader :directive
31
+ def set_style
32
+ Array(style).map { |s| Style.set(s) }.join
33
+ end
34
+
35
+ def position
36
+ directives.fetch(:position, [])
37
+ end
38
+
39
+ def colour
40
+ directives.fetch(:colour, [])
41
+ end
29
42
 
30
- def valid_directive?
31
- directive.is_a?(Array) || directive.is_a?(Symbol)
43
+ def style
44
+ directives.fetch(:style, [])
32
45
  end
33
46
  end
34
47
  end
@@ -56,7 +56,12 @@ module Vedeu
56
56
  end
57
57
 
58
58
  def values
59
- defaults.merge(@values)
59
+ defaults.merge(auto)
60
+ end
61
+
62
+ def auto
63
+ @values.delete_if { |k, v| k == :width && v == :auto }
64
+ @values.delete_if { |k, v| k == :height && v == :auto }
60
65
  end
61
66
 
62
67
  def defaults
@@ -1,13 +1,18 @@
1
1
  module Vedeu
2
2
  class Position
3
3
  class << self
4
- def set(y = 0, x = 0)
4
+ def set(y = nil, x = nil)
5
+ return '' if y.nil? || x.nil?
6
+
5
7
  new(y, x).set
6
8
  end
7
- alias_method :reset, :set
9
+
10
+ def reset
11
+ new(0, 0).set
12
+ end
8
13
  end
9
14
 
10
- def initialize(y = 0, x = 0)
15
+ def initialize(y = nil, x = nil)
11
16
  @y, @x = y, x
12
17
  end
13
18
 
@@ -0,0 +1,84 @@
1
+ module Vedeu
2
+ class Wordwrap
3
+ class << self
4
+ def this(value, options = {})
5
+ new(value, options).reformat
6
+ end
7
+ end
8
+
9
+ def initialize(value, options = {})
10
+ @value, @options = value, options
11
+ end
12
+
13
+ def reformat
14
+ return pruned if prune?
15
+ wordwrapped
16
+ end
17
+
18
+ def wordwrapped
19
+ processed = []
20
+ value.split(/\n/).map do |unprocessed|
21
+ line_length = 0
22
+ reformatted = []
23
+
24
+ unprocessed.split(/\s/).map do |word|
25
+ word_length = word.length + 1
26
+
27
+ if (line_length += word_length) >= maximum_width
28
+ line_length = word_length
29
+ processed << reformatted
30
+ reformatted = []
31
+ end
32
+
33
+ reformatted << word
34
+ end
35
+
36
+ processed << reformatted
37
+ end
38
+
39
+ output(processed)
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :value, :options
45
+
46
+ def output(paragraph)
47
+ paragraph.reduce([]) do |output, line|
48
+ output << line.join(' ')
49
+ end.join("\n")
50
+ end
51
+
52
+ def pruned
53
+ return value if value.size <= pruned_width
54
+ [
55
+ value.chomp.slice(0..pruned_width),
56
+ '...',
57
+ Esc.reset
58
+ ].join
59
+ end
60
+
61
+ def pruned_width
62
+ maximum_width - 3
63
+ end
64
+
65
+ def prune?
66
+ options.fetch(:prune)
67
+ end
68
+
69
+ def maximum_width
70
+ options.fetch(:width)
71
+ end
72
+
73
+ def options
74
+ defaults.merge!(@options)
75
+ end
76
+
77
+ def defaults
78
+ {
79
+ width: 70,
80
+ prune: false
81
+ }
82
+ end
83
+ end
84
+ end
data/lib/vedeu/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vedeu
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -2,14 +2,24 @@ require_relative '../../test_helper'
2
2
 
3
3
  module Vedeu
4
4
  describe Application do
5
- let(:described_class) { Application }
6
- let(:instance) { described_class.new(options) }
7
- let(:options) { {} }
5
+ let(:described_class) { Application }
6
+ let(:described_instance) { described_class.new(options) }
7
+ let(:options) { {} }
8
+
9
+ it { described_instance.must_be_instance_of(Application) }
8
10
 
9
11
  describe '.start' do
10
- subject { described_class.start(options) }
12
+ let(:subject) { described_class.start(options) }
13
+ let(:interfaces) { mock("Interfaces", event_loop: nil,
14
+ initial_state: nil) }
15
+
16
+ before do
17
+ Terminal.stubs(:open).yields(self)
18
+ Terminal.stubs(:close)
19
+ Interfaces.stubs(:defined).returns(interfaces)
20
+ end
11
21
 
12
- it { skip }
22
+ it { subject.must_be_instance_of(NilClass) }
13
23
  end
14
24
  end
15
25
  end
@@ -2,21 +2,21 @@ require_relative '../../../test_helper'
2
2
 
3
3
  module Vedeu
4
4
  describe Dummy do
5
- let(:described_class) { Dummy }
6
- let(:instance) { described_class.new }
5
+ let(:described_class) { Dummy }
6
+ let(:described_instance) { described_class.new }
7
7
 
8
8
  describe '#initial_state' do
9
- subject { instance.initial_state }
9
+ let(:subject) { described_instance.initial_state }
10
10
 
11
11
  it { subject.must_be_instance_of(NilClass) }
12
12
  end
13
13
 
14
14
  describe '#input' do
15
- subject { instance.input }
15
+ let(:subject) { described_instance.input }
16
16
  end
17
17
 
18
18
  describe '#output' do
19
- subject { instance.output }
19
+ let(:subject) { described_instance.output }
20
20
  end
21
21
  end
22
22
  end
@@ -9,31 +9,41 @@ module Vedeu
9
9
  it { described_instance.must_be_instance_of(Interface) }
10
10
 
11
11
  describe '#initial_state' do
12
- subject { described_instance.initial_state }
12
+ let(:subject) { described_instance.initial_state }
13
13
 
14
14
  it { proc { subject }.must_raise(NotImplementedError) }
15
15
  end
16
16
 
17
17
  describe '#event_loop' do
18
- subject { described_instance.event_loop }
18
+ let(:subject) { described_instance.event_loop }
19
19
 
20
20
  it { skip }
21
21
  end
22
22
 
23
23
  describe '#input' do
24
- subject { described_instance.input }
24
+ let(:subject) { described_instance.input }
25
25
 
26
- it { skip }
26
+ before do
27
+ Terminal.stubs(:input).returns('some input')
28
+ Commands.stubs(:execute).returns('some output')
29
+ end
30
+
31
+ it { subject.must_be_instance_of(String) }
27
32
  end
28
33
 
29
34
  describe '#output' do
30
- subject { described_instance.output }
35
+ let(:subject) { described_instance.output(command) }
36
+ let(:command) { mock }
31
37
 
32
- it { skip }
38
+ before { Compositor.stubs(:arrange).returns([]) }
39
+
40
+ it 'sends the output of the command to the compositor' do
41
+ subject.must_be_instance_of(Array)
42
+ end
33
43
  end
34
44
 
35
45
  describe '#geometry' do
36
- subject { described_instance.geometry }
46
+ let(:subject) { described_instance.geometry }
37
47
 
38
48
  it { subject.must_be_instance_of(Geometry) }
39
49
  end