ansi-sys 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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