ansi-sys 0.2.0

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.
@@ -0,0 +1,17 @@
1
+ <pre class="screen" style="background-color: black; padding: 0.5em; color: white; width: 40.0em">
2
+
3
+ As a Hiki plugin
4
+ <span style="color: fuchsia">- should render an HTML fragment as expected (ERROR - 1)
5
+
6
+ </span>1)
7
+ <span style="color: fuchsia">NoMethodError in 'As a Hiki plugin should render an HTML fragment as expected'
8
+ undefined method `join' for 114:Fixnum
9
+ </span>lib/ansisys.rb:23:in `hash_to_styles'
10
+ ./spec/hiki_spec.rb:27:in `map'
11
+ lib/ansisys.rb:23:in `hash_to_styles'
12
+ lib/ansisys.rb:589:in `ansi_screen'
13
+ ./spec/hiki_spec.rb:37:
14
+
15
+ Finished in 0.158791 seconds
16
+
17
+ <span style="color: red">1 example, 1 failure</span></pre>
@@ -0,0 +1,16 @@
1
+
2
+ As a Hiki plugin
3
+ - should render an HTML fragment as expected (ERROR - 1)
4
+
5
+ 1)
6
+ NoMethodError in 'As a Hiki plugin should render an HTML fragment as expected'
7
+ undefined method `join' for 114:Fixnum
8
+ lib/ansisys.rb:23:in `hash_to_styles'
9
+ ./spec/hiki_spec.rb:27:in `map'
10
+ lib/ansisys.rb:23:in `hash_to_styles'
11
+ lib/ansisys.rb:589:in `ansi_screen'
12
+ ./spec/hiki_spec.rb:37:
13
+
14
+ Finished in 0.158791 seconds
15
+
16
+ 1 example, 1 failure
@@ -0,0 +1,32 @@
1
+ $:.unshift('lib')
2
+ require 'ansisys'
3
+
4
+ unless defined?(:SGR)
5
+ class SGR
6
+ end
7
+ end
8
+
9
+ include AnsiSys
10
+ describe "Normal characters echoed on a Screen" do
11
+ before do
12
+ @string = "Test string <HELLO>"
13
+ @char = Characters.new(@string, SGR.new)
14
+ @screen = Screen.new
15
+ @cursor = Cursor.new
16
+ end
17
+
18
+ it "should usually be distributed identical string onto screen" do
19
+ @char.echo_on(@screen, @cursor)
20
+ @screen.render(:text).should == <<_SCREEN.chomp
21
+ Test string <HELLO>
22
+ _SCREEN
23
+ end
24
+
25
+ it "should be HTML escaped when rendered as an HTML fragment" do
26
+ @char.echo_on(@screen, @cursor)
27
+ @screen.render(:html).should == <<_SCREEN.chomp
28
+ <pre class="screen">\nTest string &lt;HELLO&gt;</pre>
29
+ _SCREEN
30
+ end
31
+ end
32
+
@@ -0,0 +1,45 @@
1
+ $:.unshift('lib')
2
+ require 'ansisys'
3
+
4
+ include AnsiSys
5
+ # This spec is dependent upon Screen, Cursor, and SGR
6
+
7
+ def echo(string, col, row)
8
+ @screen = Screen.new
9
+ @char = Characters.new(string, SGR.new)
10
+ @cursor = Cursor.new(col, row, 80, 25)
11
+ @char.echo_on(@screen, @cursor)
12
+ end
13
+
14
+ describe Characters, "when rendered at the right edge" do
15
+ before do
16
+ echo("Test string <HELLO>", 75, 1)
17
+ end
18
+
19
+ it "should fold the string at the right edge" do
20
+ @cursor.cur_row.should == 2
21
+ @cursor.cur_col.should == 14
22
+ end
23
+ end
24
+
25
+ describe Characters, "with Japanese characters" do
26
+ before do
27
+ $KCODE = 'u'
28
+ echo("\346\227\245\346\234\254\350\252\236", 1, 1) # `Nihongo' in UTF-8
29
+ end
30
+
31
+ it "sohuld assume each occupies 2 columns" do
32
+ @cursor.cur_col.should == 7
33
+ end
34
+ end
35
+
36
+ describe Characters, "with tab" do
37
+ before do
38
+ echo("\t", 1, 1)
39
+ end
40
+
41
+ it "sohuld assume it occupies 8 columns" do
42
+ @cursor.cur_col.should == 9
43
+ end
44
+ end
45
+
@@ -0,0 +1,165 @@
1
+ $:.unshift('lib')
2
+ require 'ansisys'
3
+
4
+ include AnsiSys
5
+ describe Cursor, 'when initialized' do
6
+ before do
7
+ @cursor = Cursor.new
8
+ end
9
+
10
+ it "should be at (1,1) on screen" do
11
+ @cursor.cur_col.should == 1
12
+ @cursor.cur_row.should == 1
13
+ end
14
+
15
+ it "should be in (80,25) screen" do
16
+ @cursor.max_col.should == 80
17
+ @cursor.max_row.should == 25
18
+ end
19
+ end
20
+
21
+ describe Cursor, 'when moved normally' do
22
+ before do
23
+ @cursor = Cursor.new
24
+ @cursor.instance_variable_set('@cur_col', 5)
25
+ @cursor.instance_variable_set('@cur_row', 5)
26
+ end
27
+
28
+ it "should move up with code CUU" do
29
+ lambda{@cursor.apply_code!(%w(A))}.should change(@cursor, :cur_row).by(-1)
30
+ lambda{@cursor.apply_code!(%w(1 A))}.should change(@cursor, :cur_row).by(-1)
31
+ lambda{@cursor.apply_code!(%w(2 A))}.should change(@cursor, :cur_row).by(-2)
32
+ end
33
+
34
+ it "should move down with code CUD" do
35
+ lambda{@cursor.apply_code!(%w(B))}.should change(@cursor, :cur_row).by(1)
36
+ lambda{@cursor.apply_code!(%w(1 B))}.should change(@cursor, :cur_row).by(1)
37
+ lambda{@cursor.apply_code!(%w(2 B))}.should change(@cursor, :cur_row).by(2)
38
+ end
39
+
40
+ it "should move to right with code CUF" do
41
+ lambda{@cursor.apply_code!(%w(C))}.should change(@cursor, :cur_col).by(1)
42
+ lambda{@cursor.apply_code!(%w(1 C))}.should change(@cursor, :cur_col).by(1)
43
+ lambda{@cursor.apply_code!(%w(2 C))}.should change(@cursor, :cur_col).by(2)
44
+ end
45
+
46
+ it "should move to left with code CUB" do
47
+ lambda{@cursor.apply_code!(%w(D))}.should change(@cursor, :cur_col).by(-1)
48
+ lambda{@cursor.apply_code!(%w(1 D))}.should change(@cursor, :cur_col).by(-1)
49
+ lambda{@cursor.apply_code!(%w(2 D))}.should change(@cursor, :cur_col).by(-2)
50
+ end
51
+
52
+ it "should move to beggining of lower line with CNL" do
53
+ [[1, %w(E)], [1, %w(1 E)], [2, %w(2 E)]].each do |d, code|
54
+ lambda{@cursor.apply_code!(code)}.should change(@cursor, :cur_row).by(d)
55
+ @cursor.cur_col.should == 1
56
+ end
57
+ end
58
+
59
+ it "should move to beggining of upper line with CPL" do
60
+ [[-1, %w(F)], [-1, %w(1 F)], [-2, %w(2 F)]].each do |d, code|
61
+ lambda{@cursor.apply_code!(code)}.should change(@cursor, :cur_row).by(d)
62
+ @cursor.cur_col.should == 1
63
+ end
64
+ end
65
+
66
+ it "should move to specified column with CHA" do
67
+ [[1, %w(G)], [1, %w(1 G)], [2, %w(2 G)]].each do |c, code|
68
+ lambda{@cursor.apply_code!(code)}.should_not change(@cursor, :cur_row)
69
+ @cursor.cur_col.should == c
70
+ end
71
+ end
72
+
73
+ it "should move to specified position with CUP and HVP" do
74
+ %w(H f).each do |letter|
75
+ [
76
+ # row, column, code
77
+ [1, 5, [nil, '5']],
78
+ [1, 5, ['', '5']],
79
+ [1, 5, ['1', '5']],
80
+ [17, 1, ['17', nil]],
81
+ [17, 1, ['17', '']],
82
+ [17, 1, ['17', '1']],
83
+ [9, 8, ['9', '8']],
84
+ ].each do |r, c, code|
85
+ @cursor.apply_code!(code + [letter])
86
+ @cursor.cur_col.should == c
87
+ @cursor.cur_row.should == r
88
+ end
89
+ end
90
+ end
91
+
92
+ end
93
+
94
+ describe Cursor, 'when tried to be moved beyond edge' do
95
+ before do
96
+ @cursor = Cursor.new
97
+ end
98
+
99
+ it "should not move with code CUU" do
100
+ @cursor.instance_variable_set('@cur_row', 1)
101
+ lambda{@cursor.apply_code!(%w(1 A))}.should_not change(@cursor, :cur_row)
102
+ end
103
+
104
+ it "should not move with code CUD" do
105
+ @cursor.instance_variable_set('@cur_row', @cursor.max_row)
106
+ lambda{@cursor.apply_code!(%w(1 B))}.should_not change(@cursor, :cur_row)
107
+ end
108
+
109
+ it "should not move with code CUF" do
110
+ @cursor.instance_variable_set('@cur_col', @cursor.max_col)
111
+ lambda{@cursor.apply_code!(%w(1 C))}.should_not change(@cursor, :cur_col)
112
+ end
113
+
114
+ it "should not move with code CUB" do
115
+ @cursor.instance_variable_set('@cur_col', 1)
116
+ lambda{@cursor.apply_code!(%w(1 D))}.should_not change(@cursor, :cur_col)
117
+ end
118
+
119
+ it "should make screen longer with code CNL" do
120
+ @cursor.instance_variable_set('@cur_row', @cursor.max_row)
121
+ lambda{@cursor.apply_code!(%w(1 E))}.should change(@cursor, :max_row).by(1)
122
+ end
123
+
124
+ it "should not change row with code CNL" do
125
+ @cursor.instance_variable_set('@cur_row', 1)
126
+ lambda{@cursor.apply_code!(%w(1 F))}.should_not change(@cursor, :cur_row)
127
+ end
128
+
129
+ it "should move to edge column with code CHA" do
130
+ lambda{@cursor.apply_code!(%w(99 G))}.should change(@cursor, :cur_col).to(@cursor.max_col)
131
+ end
132
+
133
+ end
134
+
135
+ describe Cursor, 'when advanced' do
136
+ it "should move to the next column for a usual move" do
137
+ cursor = Cursor.new(1, 1, 80, 25)
138
+ lambda{cursor.advance!}.should change(cursor, :cur_col).by(1)
139
+ [1, 2, 3].each do |w|
140
+ lambda{cursor.advance!(w)}.should change(cursor, :cur_col).by(w)
141
+ end
142
+ cursor = Cursor.new(79, 1, 80, 25)
143
+ lambda{cursor.advance!}.should change(cursor, :cur_col).by(1)
144
+ end
145
+
146
+ it "should move to the next row from the right edge" do
147
+ cursor = Cursor.new(80, 1, 80, 25)
148
+ lambda{cursor.advance!(1)}.should change(cursor, :cur_row).by(1)
149
+ cursor.cur_col.should == 1
150
+ end
151
+
152
+ it "should return nil for a usual move" do
153
+ cursor = Cursor.new(1, 1, 80, 25)
154
+ [1, 2, 3].each do |w|
155
+ cursor.advance!(w).should == nil
156
+ end
157
+ end
158
+
159
+ it "should return \"\\n\" going beyond the right edge" do
160
+ cursor = Cursor.new(80, 1, 80, 25)
161
+ cursor.advance!(1).should == "\n"
162
+ end
163
+
164
+ end
165
+
@@ -0,0 +1,39 @@
1
+ describe "As a Hiki plugin" do
2
+ before do
3
+ include 'webrick'
4
+ class String
5
+ def escape
6
+ WEBrick::HTTPUtils.escape(self)
7
+ end
8
+ end
9
+
10
+ module Hiki
11
+ class Conf
12
+ def cache_path
13
+ './spec'
14
+ end
15
+ end
16
+
17
+ class PluginError < StandardError; end
18
+
19
+ class Plugin
20
+ def initialize
21
+ @page = '.'
22
+ @conf = Conf.new
23
+ end
24
+
25
+ def load_plugin
26
+ lib = 'lib/ansisys.rb'
27
+ instance_eval(File.read(lib), lib, 1)
28
+ end
29
+ end
30
+ end
31
+
32
+ @plugin = Hiki::Plugin.new
33
+ @plugin.load_plugin
34
+ end
35
+
36
+ it "should render an HTML fragment as expected" do
37
+ @plugin.ansi_screen('test_data.txt').should == File.read('spec/attach/test_data.html')
38
+ end
39
+ end
@@ -0,0 +1,95 @@
1
+ $:.unshift('lib')
2
+ require 'ansisys'
3
+
4
+ include AnsiSys
5
+ describe Lexer::PARAMETER_AND_LETTER, "a regexp for parameters and a letter" do
6
+ it 'should not match partial code' do
7
+ m = Lexer::PARAMETER_AND_LETTER.match("32")
8
+ m.should == nil
9
+ end
10
+
11
+ it 'should match a code without parameter' do
12
+ m = Lexer::PARAMETER_AND_LETTER.match("m")
13
+ m.should_not == nil
14
+ m[2].should == 'm'
15
+ end
16
+
17
+ it 'should match a code with a parameter' do
18
+ m = Lexer::PARAMETER_AND_LETTER.match("32m")
19
+ m.should_not == nil
20
+ m[1].should == '32'
21
+ m[2].should == 'm'
22
+ end
23
+
24
+ it 'should match a code with two parameters' do
25
+ m = Lexer::PARAMETER_AND_LETTER.match("32;0m")
26
+ m.should_not == nil
27
+ m[1].should == '32;0'
28
+ m[2].should == 'm'
29
+ end
30
+
31
+ it 'should match a code with three parameters' do
32
+ m = Lexer::PARAMETER_AND_LETTER.match("32;0;1m")
33
+ m.should_not == nil
34
+ m[1].should == '32;0;1'
35
+ m[2].should == 'm'
36
+ end
37
+
38
+ it 'should match a code with three and omitted parameters' do
39
+ m = Lexer::PARAMETER_AND_LETTER.match("32;;1m")
40
+ m.should_not == nil
41
+ m[1].should == '32;;1'
42
+ m[2].should == 'm'
43
+ end
44
+ end
45
+
46
+ describe Lexer do
47
+ before do
48
+ @lexer = Lexer.new(["\x1b["])
49
+ end
50
+
51
+ it 'should return usual string as it is' do
52
+ x = 'Usual string.'
53
+ @lexer.push(x)
54
+ @lexer.buffer.should == x
55
+ @lexer.lex!.should == [[:string, x]]
56
+ @lexer.buffer.should be_empty
57
+ end
58
+
59
+ it 'should return nothing if a code is not complete' do
60
+ @lexer.push("\x1b[32")
61
+ @lexer.lex!.should be_empty
62
+ @lexer.buffer.should_not be_empty
63
+ end
64
+
65
+ it 'should return string and code' do
66
+ @lexer.push("string one\x1b[32mstring two")
67
+ @lexer.lex!.should == [[:string, 'string one'], [:code, '32m'], [:string, 'string two']]
68
+ @lexer.buffer.should be_empty
69
+ end
70
+
71
+ it 'should translate LF to a codes E' do
72
+ @lexer.push("line one\nline two\n")
73
+ @lexer.lex!.should == [[:string, 'line one'], [:code, 'E'], [:string, 'line two'], [:code, 'E']]
74
+ @lexer.buffer.should be_empty
75
+ end
76
+
77
+ it 'should translate CRLF to a code E' do
78
+ @lexer.push("line one\r\nline two\r\n")
79
+ @lexer.lex!.should == [[:string, 'line one'], [:code, 'E'], [:string, 'line two'], [:code, 'E']]
80
+ @lexer.buffer.should be_empty
81
+ end
82
+
83
+ it 'should translate LFCR to a coden E' do
84
+ @lexer.push("line one\n\rline two\n\r")
85
+ @lexer.lex!.should == [[:string, 'line one'], [:code, 'E'], [:string, 'line two'], [:code, 'E']]
86
+ @lexer.buffer.should be_empty
87
+ end
88
+
89
+ it 'should translate CR to a code B' do
90
+ @lexer.push("line one\rline two\r")
91
+ @lexer.lex!.should == [[:string, 'line one'], [:code, 'B'], [:string, 'line two'], [:code, 'B']]
92
+ @lexer.buffer.should be_empty
93
+ end
94
+
95
+ end
@@ -0,0 +1,164 @@
1
+ $:.unshift('lib')
2
+ require 'ansisys'
3
+ unless defined?(:SGR)
4
+ class SGR
5
+ end
6
+ end
7
+
8
+ include AnsiSys
9
+ describe Screen, "when rendered as a plain text" do
10
+ before do
11
+ @screen = Screen.new
12
+ @sgr = SGR.new
13
+ end
14
+
15
+ it "should store character at the given location" do
16
+ @screen.write('t', 1, 3, 5, @sgr)
17
+ @screen.instance_variable_get(:@lines)[5][3].should == ['t', 1, SGR.new]
18
+ end
19
+
20
+ it "should overwrite character" do
21
+ @screen.write('t', 1, 3, 5, @sgr)
22
+ @screen.write('u', 1, 3, 5, @sgr)
23
+ @screen.instance_variable_get(:@lines)[5][3].should == ['u', 1, SGR.new]
24
+ end
25
+ end
26
+
27
+ describe Screen, "when rendered" do
28
+ before do
29
+ @screen = Screen.new
30
+ @sgr = SGR.new
31
+ end
32
+
33
+ it "should render Ascii characters" do
34
+ @screen.write('h', 1, 3, 2, @sgr)
35
+ @screen.write('e', 1, 4, 2, @sgr)
36
+ @screen.write('l', 1, 5, 2, @sgr)
37
+ @screen.write('l', 1, 6, 2, @sgr)
38
+ @screen.write('o', 1, 7, 2, @sgr)
39
+ @screen.render(:text).should == <<_SCREEN.chomp
40
+
41
+ hello
42
+ _SCREEN
43
+ end
44
+
45
+ it "should render wide characters" do
46
+ @screen.write('h-', 2, 3, 2, @sgr)
47
+ @screen.write('e-', 2, 5, 2, @sgr)
48
+ @screen.write('l-', 2, 7, 2, @sgr)
49
+ @screen.write('l-', 2, 9, 2, @sgr)
50
+ @screen.write('o-', 2, 11, 2, @sgr)
51
+ @screen.render(:text).should == <<_SCREEN.chomp
52
+
53
+ h-e-l-l-o-
54
+ _SCREEN
55
+ end
56
+ end
57
+
58
+ describe Screen, "when rendered as an HTML fragment" do
59
+ before do
60
+ @screen = Screen.new
61
+ @sgr = SGR.new
62
+ @screen.write('h', 1, 3, 1, @sgr)
63
+ @screen.write('e', 1, 4, 1, @sgr)
64
+ @screen.write('l', 1, 5, 1, @sgr)
65
+ @screen.write('l', 1, 6, 1, @sgr)
66
+ @screen.write('o', 1, 7, 1, @sgr)
67
+ end
68
+
69
+ it "should be surrounded with <pre>" do
70
+ @screen.render(:html).should == <<_SCREEN.chomp
71
+ <pre class="screen">\n hello</pre>
72
+ _SCREEN
73
+ end
74
+
75
+ it "should change colors" do
76
+ @sgr.apply_code!(%w(32 m))
77
+ @screen.write(':', 1, 1, 1, @sgr)
78
+ @screen.write(')', 1, 2, 1, @sgr)
79
+ @screen.render(:html).should == <<_SCREEN.chomp
80
+ <pre class="screen">\n<span style="color: green">:)</span>hello</pre>
81
+ _SCREEN
82
+ end
83
+ end
84
+
85
+ describe "screen with default colors set", :shared => true do
86
+ it "should only specify colors of special color letters" do
87
+ @screen.render(:html).should == <<_SCREEN.chomp
88
+ <pre class="screen">\n<span style="color: green">:)</span>hello</pre>
89
+ _SCREEN
90
+ end
91
+ end
92
+
93
+ describe Screen, "with default colors" do
94
+ before do
95
+ @screen = Screen.new
96
+ @sgr = SGR.new
97
+ @screen.write('h', 1, 3, 1, @sgr)
98
+ @screen.write('e', 1, 4, 1, @sgr)
99
+ @screen.write('l', 1, 5, 1, @sgr)
100
+ @screen.write('l', 1, 6, 1, @sgr)
101
+ @screen.write('o', 1, 7, 1, @sgr)
102
+ @sgr.apply_code!(%w(32 m))
103
+ @screen.write(':', 1, 1, 1, @sgr)
104
+ @screen.write(')', 1, 2, 1, @sgr)
105
+ end
106
+
107
+ it_should_behave_like "screen with default colors set"
108
+
109
+ it "should have default css style with silver letters on black background" do
110
+ css = @screen.css_style
111
+ css.should include('color: silver;')
112
+ css.should include('background-color: black;')
113
+ end
114
+ end
115
+
116
+ describe Screen, "with inverted colors" do
117
+ before do
118
+ @screen = Screen.new(Screen.default_css_colors(true))
119
+ @sgr = SGR.new
120
+ @screen.write('h', 1, 3, 1, @sgr)
121
+ @screen.write('e', 1, 4, 1, @sgr)
122
+ @screen.write('l', 1, 5, 1, @sgr)
123
+ @screen.write('l', 1, 6, 1, @sgr)
124
+ @screen.write('o', 1, 7, 1, @sgr)
125
+ @sgr.apply_code!(%w(32 m))
126
+ @screen.write(':', 1, 1, 1, @sgr)
127
+ @screen.write(')', 1, 2, 1, @sgr)
128
+ end
129
+
130
+ it_should_behave_like "screen with default colors set"
131
+
132
+ it "should have default css style with black letters on white background" do
133
+ css = @screen.css_style
134
+ css.should include('color: black;')
135
+ css.should include('background-color: silver;')
136
+ end
137
+ end
138
+
139
+ describe Screen, "with bright colors" do
140
+ before do
141
+ @screen = Screen.new(Screen.default_css_colors(false, true))
142
+ @sgr = SGR.new
143
+ @screen.write('h', 1, 3, 1, @sgr)
144
+ @screen.write('e', 1, 4, 1, @sgr)
145
+ @screen.write('l', 1, 5, 1, @sgr)
146
+ @screen.write('l', 1, 6, 1, @sgr)
147
+ @screen.write('o', 1, 7, 1, @sgr)
148
+ @sgr.apply_code!(%w(32 m))
149
+ @screen.write(':', 1, 1, 1, @sgr)
150
+ @screen.write(')', 1, 2, 1, @sgr)
151
+ end
152
+
153
+ it "should have colors as specified" do
154
+ @screen.render(:html).should == <<_SCREEN.chomp
155
+ <pre class="screen">\n<span style="color: lime">:)</span>hello</pre>
156
+ _SCREEN
157
+ end
158
+
159
+ it "should have default css style with black letters on white background" do
160
+ css = @screen.css_style
161
+ css.should include('color: white;')
162
+ css.should include('background-color: black;')
163
+ end
164
+ end