console 0.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +15 -0
- data/Gemfile +8 -0
- data/README.md +165 -0
- data/Rakefile +13 -0
- data/console.gemspec +24 -0
- data/lib/console.rb +65 -0
- data/lib/console/buffer.rb +40 -0
- data/lib/console/capture.rb +66 -0
- data/lib/console/error.rb +76 -0
- data/lib/console/filter.rb +119 -0
- data/lib/console/generic.rb +26 -0
- data/lib/console/logger.rb +31 -0
- data/lib/console/serialized/logger.rb +71 -0
- data/lib/console/shell.rb +65 -0
- data/lib/console/split.rb +42 -0
- data/lib/console/terminal.rb +21 -0
- data/lib/console/terminal/logger.rb +150 -0
- data/lib/console/terminal/text.rb +67 -0
- data/lib/console/terminal/xterm.rb +80 -0
- data/lib/console/version.rb +23 -0
- data/proposal.md +84 -0
- metadata +107 -58
- data/README +0 -51
- data/ext/console/console.c +0 -271
- data/ext/console/extconf.rb +0 -2
- data/lib/console/string.rb +0 -37
- data/test/console.rb +0 -126
data/ext/console/console.c
DELETED
@@ -1,271 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* console.c -- ruby console library
|
3
|
-
* Author: William Morgan (mailto: wmorgan-ruby-console@masanjin.net)
|
4
|
-
* Copyright: Copyright 2010 William Morgan
|
5
|
-
* License: same terms as Ruby itself
|
6
|
-
*/
|
7
|
-
|
8
|
-
#include <wchar.h>
|
9
|
-
#include <stdlib.h>
|
10
|
-
#include <ruby.h>
|
11
|
-
#include <locale.h>
|
12
|
-
|
13
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
14
|
-
#include <ruby/encoding.h>
|
15
|
-
#endif
|
16
|
-
|
17
|
-
static inline int calc_width(char* string, long strlen, long byte_offset, size_t* num_bytes, size_t* num_cols) {
|
18
|
-
wchar_t wc;
|
19
|
-
size_t width = -1;
|
20
|
-
mbstate_t state;
|
21
|
-
|
22
|
-
memset(&state, 0, sizeof(state));
|
23
|
-
*num_bytes = mbrtowc(&wc, string + byte_offset, strlen - byte_offset, &state);
|
24
|
-
|
25
|
-
if(*num_bytes == (size_t)-2) {
|
26
|
-
rb_raise(rb_eArgError, "malformed string: incomplete multibyte character at position %ld", byte_offset);
|
27
|
-
return -1;
|
28
|
-
}
|
29
|
-
else if(*num_bytes == (size_t)-1) {
|
30
|
-
rb_raise(rb_eArgError, "malformed string: invalid multibyte character at position %ld", byte_offset);
|
31
|
-
return -1;
|
32
|
-
}
|
33
|
-
else if(*num_bytes == 0) {
|
34
|
-
//rb_raise(rb_eArgError, "malformed string: NULL byte at position %ld", byte_offset);
|
35
|
-
// it's fine to have a NULL byte. forge ahead!
|
36
|
-
*num_bytes = 1;
|
37
|
-
*num_cols = 0;
|
38
|
-
}
|
39
|
-
else {
|
40
|
-
*num_cols = wcwidth(wc);
|
41
|
-
}
|
42
|
-
|
43
|
-
return 0;
|
44
|
-
}
|
45
|
-
|
46
|
-
/*
|
47
|
-
* call-seq: init_locale!
|
48
|
-
*
|
49
|
-
* Sets the program's current locale from the appropriate environment variables.
|
50
|
-
* (see `man 3 setlocale` for details).
|
51
|
-
*
|
52
|
-
* Equivalent to:
|
53
|
-
* char* old_locale = setlocale(LC_ALL, NULL);
|
54
|
-
* return old_locale;
|
55
|
-
*
|
56
|
-
* in C.
|
57
|
-
*
|
58
|
-
* If you are using Ruby 1.8, you *must* call this at least once before calling
|
59
|
-
* the other methods in this package. Otherwise, using non-ASCII strings will
|
60
|
-
* be considered invalid, and #display_width and #display_slice will raise
|
61
|
-
* ArgumentErrors.
|
62
|
-
*
|
63
|
-
* Ruby 1.9 users do not need to call this, since Ruby 1.9 appears to set the
|
64
|
-
* locale in this manner already. Calling it won't matter, however.
|
65
|
-
*
|
66
|
-
* Returns a string representing the old locale. If you wish to change locales
|
67
|
-
* several times, you can use this value to return to the previous locale.
|
68
|
-
* Otherwise, just ignore it.
|
69
|
-
*/
|
70
|
-
|
71
|
-
static VALUE init_locale(VALUE v_self) {
|
72
|
-
char* old_locale = setlocale(LC_ALL, NULL);
|
73
|
-
setlocale(LC_ALL, ""); // set ctype locale according to appropriate env vars
|
74
|
-
|
75
|
-
return rb_str_new2(old_locale);
|
76
|
-
}
|
77
|
-
|
78
|
-
/*
|
79
|
-
* call-seq: display_width(string)
|
80
|
-
*
|
81
|
-
* Returns the display width of <code>string</code>, that is, the number of
|
82
|
-
* columns that the string will take up when printed to screen. This is
|
83
|
-
* different from both the number of characters and the number of bytes in a
|
84
|
-
* string.
|
85
|
-
*
|
86
|
-
* In Ruby 1.8, the input string is assumed to be in the current locale's
|
87
|
-
* encoding. If it isn't, an ArgumentError will be raised. Be sure to call
|
88
|
-
* init_locale! before calling this method! Otherwise every non-ASCII string
|
89
|
-
* will trigger an ArgumentError.
|
90
|
-
*
|
91
|
-
* In Ruby 1.9, the string will be automatically converted from its encoding
|
92
|
-
* into the current locale's encoding for processing.
|
93
|
-
*
|
94
|
-
* Throws an ArgumentError when it encounters an invalid character. On Ruby
|
95
|
-
* 1.8, this includes any string not in the current locale's encoding. On Ruby
|
96
|
-
* 1.9, this should only occur if Ruby is unable to convert the string from its
|
97
|
-
* encoding into the current locale's encoding.
|
98
|
-
*/
|
99
|
-
static VALUE display_width(VALUE v_self, VALUE v_string) {
|
100
|
-
Check_Type(v_string, T_STRING);
|
101
|
-
|
102
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
103
|
-
// convert from whatever encoding it's in.
|
104
|
-
// TODO: do i have to use rb_protect to relay any exceptions?
|
105
|
-
v_string = rb_str_encode(v_string, rb_enc_from_encoding(rb_locale_encoding()), 0, Qnil);
|
106
|
-
#endif
|
107
|
-
|
108
|
-
char* string = RSTRING_PTR(v_string);
|
109
|
-
|
110
|
-
long display_width = 0;
|
111
|
-
long strlen = RSTRING_LEN(v_string);
|
112
|
-
long offset = 0;
|
113
|
-
|
114
|
-
while(offset < strlen) {
|
115
|
-
size_t num_bytes, num_cols;
|
116
|
-
int err = calc_width(string, strlen, offset, &num_bytes, &num_cols);
|
117
|
-
if(err) break;
|
118
|
-
|
119
|
-
display_width += num_cols;
|
120
|
-
offset += num_bytes;
|
121
|
-
}
|
122
|
-
|
123
|
-
return LONG2NUM(display_width);
|
124
|
-
}
|
125
|
-
|
126
|
-
static const char* default_pad_string = " ";
|
127
|
-
|
128
|
-
/*
|
129
|
-
* call-seq:
|
130
|
-
* display_slice(string, start_offset, display_width=1, pad_string=" ")
|
131
|
-
*
|
132
|
-
* Returns a slice of a string, based on display width, rather than character
|
133
|
-
* or bytes. I.e, the <code>start_offset</code> and <code>display_width</code>
|
134
|
-
* offsets index the columns required to display the string, not individual
|
135
|
-
* characters or bytes.
|
136
|
-
*
|
137
|
-
* This is useful if you want to display a part of a string on screen, as you
|
138
|
-
* can pull out a specific portion based on display size.
|
139
|
-
*
|
140
|
-
* Padding: slicing can truncate multi-column characters. If the slice
|
141
|
-
* truncates a character, the string will be padded with
|
142
|
-
* <code>pad_string</code>, on the left side, right side, or both, as
|
143
|
-
* necessary. If <code>pad_string</code> is <code>nil</code> then no padding
|
144
|
-
* will be done. <code>pad_string</code> should be a single-column string for
|
145
|
-
* this to make sense.
|
146
|
-
*
|
147
|
-
* In Ruby 1.8, the input string is assumed to be in the current locale's
|
148
|
-
* encoding. If it isn't, an ArgumentError will be raised. Be sure to call
|
149
|
-
* init_locale! before calling this method! Otherwise every non-ASCII string
|
150
|
-
* will trigger an ArgumentError.
|
151
|
-
*
|
152
|
-
* In Ruby 1.9, the string will be automatically converted from its encoding
|
153
|
-
* into the current locale's encoding. Regardless of the original encoding, the
|
154
|
-
* returned string will be in the current locale's encoding.
|
155
|
-
*
|
156
|
-
* Throws an ArgumentError when it encounters an invalid character. On Ruby
|
157
|
-
* 1.8, this includes any string not in the current locale's encoding. On Ruby
|
158
|
-
* 1.9, this should only occur if Ruby is unable to convert the string from its
|
159
|
-
* encoding into the current locale's encoding.
|
160
|
-
*/
|
161
|
-
static VALUE display_slice(int argc, VALUE *argv, VALUE v_self) {
|
162
|
-
VALUE v_string, v_display_start, v_display_width, v_pad_string;
|
163
|
-
rb_scan_args(argc, argv, "22", &v_string, &v_display_start, &v_display_width, &v_pad_string);
|
164
|
-
Check_Type(v_string, T_STRING);
|
165
|
-
|
166
|
-
/* try and mimic String#slice's argument handling as much as possible */
|
167
|
-
int display_start = NUM2INT(v_display_start);
|
168
|
-
if(display_start < 0) display_start = NUM2LONG(display_width(v_self, v_string)) + display_start; // negative start means from the end of the string
|
169
|
-
if(display_start < 0) return Qnil; // but if you go too far, you fail
|
170
|
-
|
171
|
-
int display_width;
|
172
|
-
if(argc < 3) display_width = 1; // default value just like String#slice (although it makes slightly less sense)
|
173
|
-
else display_width = NUM2INT(v_display_width);
|
174
|
-
if(display_width < 0) return Qnil; // you fail
|
175
|
-
|
176
|
-
const char* pad_string;
|
177
|
-
if(argc < 4) pad_string = default_pad_string; // only fill in default if unspecified; nil is a valid value
|
178
|
-
else if(v_pad_string == Qnil) pad_string = "";
|
179
|
-
else pad_string = RSTRING_PTR(v_pad_string);
|
180
|
-
|
181
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
182
|
-
// TODO: do i have to use rb_protect to relay any exceptions?
|
183
|
-
v_string = rb_str_encode(v_string, rb_enc_from_encoding(rb_locale_encoding()), 0, Qnil);
|
184
|
-
#endif
|
185
|
-
char* string = RSTRING_PTR(v_string);
|
186
|
-
long slen = RSTRING_LEN(v_string);
|
187
|
-
|
188
|
-
// first, advance the string pointer so that we've seen display_start width characters
|
189
|
-
long current_width = 0;
|
190
|
-
long offset = 0;
|
191
|
-
while((offset < slen) && (current_width < display_start)) {
|
192
|
-
size_t num_bytes, num_cols;
|
193
|
-
int err = calc_width(string, slen, offset, &num_bytes, &num_cols);
|
194
|
-
|
195
|
-
current_width += num_cols;
|
196
|
-
offset += num_bytes;
|
197
|
-
}
|
198
|
-
|
199
|
-
/* here's a weird behavior (to me!) of String#slice that we emulate:
|
200
|
-
* if the start point is the string length itself, you get an empty
|
201
|
-
* string back; if the start point is greater than that, you get nil.
|
202
|
-
*/
|
203
|
-
if((current_width < display_start)) return Qnil;
|
204
|
-
|
205
|
-
/* determine left padding */
|
206
|
-
const char* pad_left = "";
|
207
|
-
if((current_width > display_start) && (display_width > 0)) pad_left = pad_string;
|
208
|
-
|
209
|
-
// now, advance the string_end pointer so that we've seen an additional display_width width characters
|
210
|
-
long end_offset = offset;
|
211
|
-
current_width -= display_start;
|
212
|
-
while((end_offset < slen) && (current_width < display_width)) {
|
213
|
-
size_t num_bytes, num_cols;
|
214
|
-
int err = calc_width(string, slen, end_offset, &num_bytes, &num_cols);
|
215
|
-
|
216
|
-
if((current_width + num_cols) > (size_t)display_width) break; // have to stop here
|
217
|
-
|
218
|
-
current_width += num_cols;
|
219
|
-
end_offset += num_bytes;
|
220
|
-
}
|
221
|
-
|
222
|
-
/* determine right padding */
|
223
|
-
const char* pad_right = "";
|
224
|
-
if((current_width < display_width) && (end_offset < slen)) pad_right = pad_string;
|
225
|
-
|
226
|
-
// finally, construct a new string
|
227
|
-
int bytesize = end_offset - offset;
|
228
|
-
int leftsize = strlen(pad_left);
|
229
|
-
int rightsize = strlen(pad_right);
|
230
|
-
|
231
|
-
char* new_string = calloc(bytesize + leftsize + rightsize + 1, sizeof(char));
|
232
|
-
if(leftsize > 0) strcpy(new_string, pad_left);
|
233
|
-
if(bytesize > 0) memcpy(new_string + leftsize, string + offset, bytesize * sizeof(char));
|
234
|
-
if(rightsize > 0) strcpy(new_string + leftsize + bytesize, pad_right);
|
235
|
-
|
236
|
-
(new_string + bytesize + leftsize + rightsize)[0] = 0;
|
237
|
-
|
238
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
239
|
-
return rb_enc_str_new(new_string, bytesize + leftsize + rightsize, rb_enc_get(v_string));
|
240
|
-
#else
|
241
|
-
return rb_str_new(new_string, bytesize + leftsize + rightsize);
|
242
|
-
#endif
|
243
|
-
}
|
244
|
-
|
245
|
-
/*
|
246
|
-
* A helper class for console-based programs that need to deal with non-ASCII
|
247
|
-
* code. If you are writing a curses/ncurses program, or otherwise care about
|
248
|
-
* the display width of characters on the screen, this is crucial stuff.
|
249
|
-
*
|
250
|
-
* Provides:
|
251
|
-
*
|
252
|
-
* Console.init_locale!: set the program's locale from the appropriate
|
253
|
-
* environment variables. (Ruby 1.8 programs must call this before calling any
|
254
|
-
* of the other methods. Ruby 1.9 programs can call it or skip it without
|
255
|
-
* effect.)
|
256
|
-
*
|
257
|
-
* Console.display_width: calculates the display width of a string
|
258
|
-
*
|
259
|
-
* Console.display_slice: returns a substring according to display offset
|
260
|
-
* and display width parameters.
|
261
|
-
*
|
262
|
-
*/
|
263
|
-
|
264
|
-
void Init_console() {
|
265
|
-
VALUE cConsole;
|
266
|
-
|
267
|
-
cConsole = rb_define_class("Console", rb_cObject);
|
268
|
-
rb_define_module_function(cConsole, "display_width", display_width, 1);
|
269
|
-
rb_define_module_function(cConsole, "display_slice", display_slice, -1);
|
270
|
-
rb_define_module_function(cConsole, "init_locale!", init_locale, 0);
|
271
|
-
}
|
data/ext/console/extconf.rb
DELETED
data/lib/console/string.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
## lib/console/string.rb -- include Console methods into String
|
4
|
-
## Author: William Morgan (mailto: wmorgan-ruby-console@masanjin.net)
|
5
|
-
## Copyright: Copyright 2010 William Morgan
|
6
|
-
## License: same terms as Ruby itself
|
7
|
-
|
8
|
-
require 'console'
|
9
|
-
|
10
|
-
## reopen the String class and add #display_width and
|
11
|
-
## #display_slice methods directly to strings.
|
12
|
-
##
|
13
|
-
## If you include "console/string", you can call
|
14
|
-
## "能吞a".display_width
|
15
|
-
## instead of
|
16
|
-
## Console.display_width "能吞a"
|
17
|
-
##
|
18
|
-
## and
|
19
|
-
##
|
20
|
-
## "能吞a".display_slice 0, 2
|
21
|
-
## instead of
|
22
|
-
## Console.display_slice "能吞a", 0, 2
|
23
|
-
##
|
24
|
-
|
25
|
-
class String
|
26
|
-
## Returns the display width of the string. See Console.display_width for details.
|
27
|
-
def display_width; Console.display_width self end
|
28
|
-
|
29
|
-
## Returns a substring according to display-based start and offset values. See
|
30
|
-
## Console.display_slice for what this means.
|
31
|
-
##
|
32
|
-
## :call-seq:
|
33
|
-
## display_slice(start, offset=1, pad_string=" ")
|
34
|
-
##
|
35
|
-
## (rdoc fail)
|
36
|
-
def display_slice(*a); Console.display_slice self, *a end
|
37
|
-
end
|
data/test/console.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
## test/console.rb -- unit tests for ruby Console library
|
4
|
-
## Author: William Morgan (mailto: wmorgan-ruby-console@masanjin.net)
|
5
|
-
## Copyright: Copyright 2010 William Morgan
|
6
|
-
## License: same terms as Ruby itself
|
7
|
-
|
8
|
-
require 'test/unit'
|
9
|
-
require 'console'
|
10
|
-
|
11
|
-
Console.init_locale!
|
12
|
-
|
13
|
-
class ConsoleTest < ::Test::Unit::TestCase
|
14
|
-
def setup
|
15
|
-
@s = "能吞aê"
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_slice_of_zero_width_is_empty_string
|
19
|
-
assert_equal "", Console.display_slice(@s, 0, 0)
|
20
|
-
assert_equal "", Console.display_slice(@s, 1, 0)
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_slice_out_of_bounds_is_nil
|
24
|
-
assert_equal nil, Console.display_slice(@s, 100, 3)
|
25
|
-
assert_equal nil, Console.display_slice(@s, -100, 3)
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_slice_with_negative_offset
|
29
|
-
assert_equal "ê", Console.display_slice(@s, -1, 1)
|
30
|
-
assert_equal "aê", Console.display_slice(@s, -2, 2)
|
31
|
-
assert_equal "a", Console.display_slice(@s, -2, 1)
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_slice_width_argument_defaults_to_1
|
35
|
-
assert_equal "ê", Console.display_slice(@s, -1)
|
36
|
-
assert_equal "a", Console.display_slice(@s, -2)
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_slice_works_on_chinese_characters
|
40
|
-
assert_equal "能", Console.display_slice(@s, 0, 2);
|
41
|
-
assert_equal "能吞", Console.display_slice(@s, 0, 4);
|
42
|
-
assert_equal "能吞a", Console.display_slice(@s, 0, 5);
|
43
|
-
assert_equal "能吞aê", Console.display_slice(@s, 0, 6);
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_slice_with_excessive_width_is_still_cool
|
47
|
-
assert_equal "能吞aê", Console.display_slice(@s, 0, 100);
|
48
|
-
assert_equal "吞aê", Console.display_slice(@s, 2, 100);
|
49
|
-
assert_equal "aê", Console.display_slice(@s, 4, 100);
|
50
|
-
assert_equal "ê", Console.display_slice(@s, 5, 100);
|
51
|
-
assert_equal "", Console.display_slice(@s, 6, 100); # yep, we get a non-nil at this value
|
52
|
-
assert_equal nil, Console.display_slice(@s, 7, 100);
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_slice_with_the_biggest_valid_start_offset_behaves_like_String_slice_does
|
56
|
-
assert_equal "", Console.display_slice(@s, 6, 100);
|
57
|
-
assert_equal "", Console.display_slice(@s, 6, 0);
|
58
|
-
assert_equal nil, Console.display_slice(@s, 6, -1);
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_slice_misaligned_start_offsets_get_padded
|
62
|
-
assert_equal "", Console.display_slice(@s, 0, 0)
|
63
|
-
assert_equal " ", Console.display_slice(@s, 0, 1)
|
64
|
-
assert_equal "能", Console.display_slice(@s, 0, 2)
|
65
|
-
assert_equal "能 ", Console.display_slice(@s, 0, 3)
|
66
|
-
|
67
|
-
assert_equal "", Console.display_slice(@s, 1, 0)
|
68
|
-
assert_equal " ", Console.display_slice(@s, 1, 1)
|
69
|
-
assert_equal " ", Console.display_slice(@s, 1, 2)
|
70
|
-
assert_equal " 吞", Console.display_slice(@s, 1, 3)
|
71
|
-
|
72
|
-
assert_equal "", Console.display_slice(@s, 3, 0);
|
73
|
-
assert_equal " ", Console.display_slice(@s, 3, 1);
|
74
|
-
assert_equal " a", Console.display_slice(@s, 3, 2);
|
75
|
-
assert_equal " aê", Console.display_slice(@s, 3, 3);
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_slice_misaligned_start_offsets_get_padded_with_specified_character
|
79
|
-
assert_equal "", Console.display_slice(@s, 0, 0, "X")
|
80
|
-
assert_equal "X", Console.display_slice(@s, 0, 1, "X")
|
81
|
-
assert_equal "XX", Console.display_slice(@s, 1, 2, "X")
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_slice_fails_on_nonstrings
|
85
|
-
assert_raises(TypeError) { Console.display_slice :potato, 1, 1 }
|
86
|
-
assert_raises(TypeError) { Console.display_slice 3, 1, 1 }
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_display_width_empty_string_is_zero
|
90
|
-
assert_equal 0, Console.display_width("")
|
91
|
-
end
|
92
|
-
|
93
|
-
def test_display_width_works_on_ASCII_strings
|
94
|
-
assert_equal 1, Console.display_width("a")
|
95
|
-
assert_equal 1, Console.display_width(" ")
|
96
|
-
assert_equal 6, Console.display_width("potato")
|
97
|
-
end
|
98
|
-
|
99
|
-
def test_display_width_works_on_accented_characters
|
100
|
-
assert_equal 1, Console.display_width("ê")
|
101
|
-
assert_equal 4, Console.display_width("êêêê")
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_display_width_works_on_chinese_characters
|
105
|
-
assert_equal 2, Console.display_width("能")
|
106
|
-
assert_equal 4, Console.display_width("能吞")
|
107
|
-
end
|
108
|
-
|
109
|
-
def test_display_width_works_on_mixed_stuff
|
110
|
-
assert_equal 2, Console.display_width("aê")
|
111
|
-
assert_equal 5, Console.display_width("能吞a")
|
112
|
-
assert_equal 6, Console.display_width("能吞aê")
|
113
|
-
assert_equal 6, Console.display_width("aê能吞")
|
114
|
-
assert_equal 6, Console.display_width("a能ê吞")
|
115
|
-
assert_equal 6, Console.display_width("能aê吞")
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_display_width_fails_on_nonstrings
|
119
|
-
assert_raises(TypeError) { Console.display_width :potato }
|
120
|
-
assert_raises(TypeError) { Console.display_width 3 }
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_display_width_of_a_big_crazy_string
|
124
|
-
assert_equal 154, Console.display_width("我能吞下玻璃而不傷身體。Góa ē-tàng chia̍h po-lê, mā bē tio̍h-siong.私はガラスを食べられます。それは私を傷つけません。I can eat glass and it doesn't hurt me.")
|
125
|
-
end
|
126
|
-
end
|