coolline 0.0.1pre
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.
- data/.gemtest +0 -0
- data/lib/coolline.rb +7 -0
- data/lib/coolline/coolline.rb +369 -0
- data/lib/coolline/editor.rb +227 -0
- data/lib/coolline/handler.rb +17 -0
- data/lib/coolline/history.rb +71 -0
- data/lib/coolline/version.rb +3 -0
- data/repl.rb +28 -0
- data/test/editor_test.rb +727 -0
- data/test/helpers.rb +12 -0
- data/test/history_test.rb +85 -0
- data/test/run_all.rb +5 -0
- metadata +71 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
class Coolline
|
2
|
+
# A handler is a simple object used to match keys.
|
3
|
+
Handler = Struct.new(:char, :block) do
|
4
|
+
alias old_initialize initialize
|
5
|
+
def initialize(char, &block)
|
6
|
+
old_initialize(char, block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def ===(other_char)
|
10
|
+
char === other_char
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(cool)
|
14
|
+
block.call(cool)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class Coolline
|
2
|
+
# Class used to keep track of input. It keeps a certain amount of lines at
|
3
|
+
# most in memory, and stores them in a file.
|
4
|
+
class History
|
5
|
+
def initialize(filename, max_size = 5000)
|
6
|
+
@io = File.open(filename, 'a+')
|
7
|
+
@max_size = max_size
|
8
|
+
|
9
|
+
@lines = []
|
10
|
+
|
11
|
+
load_lines
|
12
|
+
end
|
13
|
+
|
14
|
+
def reopen(filename)
|
15
|
+
close
|
16
|
+
@io = File.open(filename, 'a+')
|
17
|
+
|
18
|
+
load_lines
|
19
|
+
end
|
20
|
+
|
21
|
+
def close
|
22
|
+
@io.close
|
23
|
+
@lines.clear
|
24
|
+
end
|
25
|
+
|
26
|
+
def search(pattern, first_line = -1)
|
27
|
+
return to_enum(:search, pattern, first_line) unless block_given?
|
28
|
+
return if size == 0
|
29
|
+
|
30
|
+
first_line %= size
|
31
|
+
@lines[0..first_line].reverse_each.with_index do |line, i|
|
32
|
+
yield line, first_line - i if pattern === line
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def <<(el)
|
37
|
+
@io.puts el
|
38
|
+
@io.flush
|
39
|
+
|
40
|
+
@lines << el.dup
|
41
|
+
@lines.delete_at(0) if @lines.size > @max_size
|
42
|
+
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
def [](id)
|
47
|
+
@lines[id]
|
48
|
+
end
|
49
|
+
|
50
|
+
def size
|
51
|
+
@lines.size
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_accessor :max_size
|
55
|
+
|
56
|
+
private
|
57
|
+
def load_lines
|
58
|
+
line_count = @io.count
|
59
|
+
@io.rewind
|
60
|
+
|
61
|
+
if line_count < @max_size
|
62
|
+
@lines.concat @io.lines.map(&:chomp)
|
63
|
+
else
|
64
|
+
@io.each do |line| # surely inefficient
|
65
|
+
@lines << line.chomp
|
66
|
+
@lines.delete_at(0) if @lines.size > @max_size
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/repl.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.join("lib", File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require 'coolline'
|
4
|
+
require 'coderay'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
cool = Coolline.new do |c|
|
8
|
+
c.transform_proc = proc do
|
9
|
+
CodeRay.scan(c.line, :ruby).term
|
10
|
+
end
|
11
|
+
|
12
|
+
c.completion_proc = proc do
|
13
|
+
word = c.completed_word
|
14
|
+
Object.constants.map(&:to_s).select { |w| w.start_with? word }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# At some point, it became frustrating to just print lines without showing any
|
19
|
+
# result.
|
20
|
+
|
21
|
+
loop do
|
22
|
+
line = cool.readline
|
23
|
+
|
24
|
+
obj = eval(line)
|
25
|
+
|
26
|
+
print "=> "
|
27
|
+
pp obj
|
28
|
+
end
|
data/test/editor_test.rb
ADDED
@@ -0,0 +1,727 @@
|
|
1
|
+
require File.expand_path("helpers.rb", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
Editor = Struct.new(:line, :pos) do
|
4
|
+
include Coolline::Editor
|
5
|
+
end
|
6
|
+
|
7
|
+
context "editor of an empty line" do
|
8
|
+
setup { Editor.new("", 0) }
|
9
|
+
|
10
|
+
context "after killing previous word" do
|
11
|
+
hookup { topic.kill_backward_word }
|
12
|
+
|
13
|
+
asserts(:pos).equals 0
|
14
|
+
asserts(:line).equals ""
|
15
|
+
end
|
16
|
+
|
17
|
+
context "after inserting a word" do
|
18
|
+
hookup { topic.insert_string "love" }
|
19
|
+
|
20
|
+
asserts(:pos).equals 4
|
21
|
+
asserts(:line).equals "love"
|
22
|
+
end
|
23
|
+
|
24
|
+
context "after moving to the next character" do
|
25
|
+
hookup { topic.forward_char }
|
26
|
+
|
27
|
+
asserts(:pos).equals 0
|
28
|
+
asserts(:line).equals ""
|
29
|
+
end
|
30
|
+
|
31
|
+
context "after moving to the previous character" do
|
32
|
+
hookup { topic.backward_char }
|
33
|
+
|
34
|
+
asserts(:pos).equals 0
|
35
|
+
asserts(:line).equals ""
|
36
|
+
end
|
37
|
+
|
38
|
+
context "after transposing characters" do
|
39
|
+
hookup { topic.transpose_chars }
|
40
|
+
|
41
|
+
asserts(:pos).equals 0
|
42
|
+
asserts(:line).equals ""
|
43
|
+
end
|
44
|
+
|
45
|
+
context "after moving one word backward" do
|
46
|
+
hookup { topic.backward_word }
|
47
|
+
|
48
|
+
asserts(:pos).equals 0
|
49
|
+
asserts(:line).equals ""
|
50
|
+
end
|
51
|
+
|
52
|
+
context "after moving one word forward" do
|
53
|
+
hookup { topic.forward_word }
|
54
|
+
|
55
|
+
asserts(:pos).equals 0
|
56
|
+
asserts(:line).equals ""
|
57
|
+
end
|
58
|
+
|
59
|
+
context "after killing the end of the line" do
|
60
|
+
hookup { topic.kill_line }
|
61
|
+
|
62
|
+
asserts(:pos).equals 0
|
63
|
+
asserts(:line).equals ""
|
64
|
+
end
|
65
|
+
|
66
|
+
context "after transposing words" do
|
67
|
+
hookup { topic.transpose_words }
|
68
|
+
|
69
|
+
asserts(:pos).equals 0
|
70
|
+
asserts(:line).equals ""
|
71
|
+
end
|
72
|
+
|
73
|
+
context "after capitalizing word" do
|
74
|
+
hookup { topic.capitalize_word }
|
75
|
+
|
76
|
+
asserts(:pos).equals 0
|
77
|
+
asserts(:line).equals ""
|
78
|
+
end
|
79
|
+
|
80
|
+
context "after lowercasing word" do
|
81
|
+
hookup { topic.lowercase_word }
|
82
|
+
|
83
|
+
asserts(:pos).equals 0
|
84
|
+
asserts(:line).equals ""
|
85
|
+
end
|
86
|
+
|
87
|
+
context "after uppercasing word" do
|
88
|
+
hookup { topic.uppercase_word }
|
89
|
+
|
90
|
+
asserts(:pos).equals 0
|
91
|
+
asserts(:line).equals ""
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "editor before many words" do
|
96
|
+
setup { Editor.new("a lovely dragon", 0) }
|
97
|
+
|
98
|
+
context "after inserting a word" do
|
99
|
+
hookup { topic.insert_string "love" }
|
100
|
+
|
101
|
+
asserts(:pos).equals 4
|
102
|
+
asserts(:line).equals "lovea lovely dragon"
|
103
|
+
end
|
104
|
+
|
105
|
+
context "after going to the end of the line" do
|
106
|
+
hookup { topic.end_of_line }
|
107
|
+
asserts(:pos).equals "a lovely dragon".size
|
108
|
+
end
|
109
|
+
|
110
|
+
context "after moving to the next character" do
|
111
|
+
hookup { topic.forward_char }
|
112
|
+
|
113
|
+
asserts(:pos).equals 1
|
114
|
+
asserts(:line).equals "a lovely dragon"
|
115
|
+
end
|
116
|
+
|
117
|
+
context "after moving to the previous character" do
|
118
|
+
hookup { topic.backward_char }
|
119
|
+
|
120
|
+
asserts(:pos).equals 0
|
121
|
+
asserts(:line).equals "a lovely dragon"
|
122
|
+
end
|
123
|
+
|
124
|
+
context "after moving one word backward" do
|
125
|
+
hookup { topic.backward_word }
|
126
|
+
|
127
|
+
asserts(:pos).equals 0
|
128
|
+
asserts(:line).equals "a lovely dragon"
|
129
|
+
end
|
130
|
+
|
131
|
+
context "after moving one word forward" do
|
132
|
+
hookup { topic.forward_word }
|
133
|
+
|
134
|
+
asserts(:pos).equals 1
|
135
|
+
asserts(:line).equals "a lovely dragon"
|
136
|
+
end
|
137
|
+
|
138
|
+
context "after killing the end of the line" do
|
139
|
+
hookup { topic.kill_line }
|
140
|
+
|
141
|
+
asserts(:pos).equals 0
|
142
|
+
asserts(:line).equals ""
|
143
|
+
end
|
144
|
+
|
145
|
+
context "after transposing words" do
|
146
|
+
hookup { topic.transpose_words }
|
147
|
+
|
148
|
+
asserts(:pos).equals 0
|
149
|
+
asserts(:line).equals "a lovely dragon"
|
150
|
+
end
|
151
|
+
|
152
|
+
context "after capitalizing word" do
|
153
|
+
hookup { topic.capitalize_word }
|
154
|
+
|
155
|
+
asserts(:pos).equals 1
|
156
|
+
asserts(:line).equals "A lovely dragon"
|
157
|
+
end
|
158
|
+
|
159
|
+
context "after lowercasing word" do
|
160
|
+
hookup { topic.lowercase_word }
|
161
|
+
|
162
|
+
asserts(:pos).equals 1
|
163
|
+
asserts(:line).equals "a lovely dragon"
|
164
|
+
end
|
165
|
+
|
166
|
+
context "after uppercasing word" do
|
167
|
+
hookup { topic.uppercase_word }
|
168
|
+
|
169
|
+
asserts(:pos).equals 1
|
170
|
+
asserts(:line).equals "A lovely dragon"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context "editor between two words" do
|
175
|
+
setup { Editor.new("foo bar", 4) } # NB: double space
|
176
|
+
|
177
|
+
context "after inserting a word" do
|
178
|
+
hookup { topic.insert_string "wow" }
|
179
|
+
|
180
|
+
asserts(:pos).equals 7
|
181
|
+
asserts(:line).equals "foo wow bar"
|
182
|
+
end
|
183
|
+
|
184
|
+
context "after killing previous word" do
|
185
|
+
hookup { topic.kill_backward_word }
|
186
|
+
|
187
|
+
asserts(:pos).equals 0
|
188
|
+
asserts(:line).equals " bar"
|
189
|
+
end
|
190
|
+
|
191
|
+
context "after killing previous character" do
|
192
|
+
hookup { topic.kill_backward_char }
|
193
|
+
|
194
|
+
asserts(:pos).equals 3
|
195
|
+
asserts(:line).equals "foo bar"
|
196
|
+
end
|
197
|
+
|
198
|
+
context "after moving one word backward" do
|
199
|
+
hookup { topic.backward_word }
|
200
|
+
|
201
|
+
asserts(:pos).equals 0
|
202
|
+
asserts(:line).equals "foo bar"
|
203
|
+
end
|
204
|
+
|
205
|
+
context "after moving one word forward" do
|
206
|
+
hookup { topic.forward_word }
|
207
|
+
|
208
|
+
asserts(:pos).equals "foo bar".size
|
209
|
+
asserts(:line).equals "foo bar"
|
210
|
+
end
|
211
|
+
|
212
|
+
context "after killing the end of the line" do
|
213
|
+
hookup { topic.kill_line }
|
214
|
+
|
215
|
+
asserts(:pos).equals 4
|
216
|
+
asserts(:line).equals "foo "
|
217
|
+
end
|
218
|
+
|
219
|
+
context "after transposing words" do
|
220
|
+
hookup { topic.transpose_words }
|
221
|
+
|
222
|
+
asserts(:pos).equals "bar foo".size
|
223
|
+
asserts(:line).equals "bar foo"
|
224
|
+
end
|
225
|
+
|
226
|
+
context "after capitalizing word" do
|
227
|
+
hookup { topic.capitalize_word }
|
228
|
+
|
229
|
+
asserts(:pos).equals "foo bar".size
|
230
|
+
asserts(:line).equals "foo Bar"
|
231
|
+
end
|
232
|
+
|
233
|
+
context "after lowercasing word" do
|
234
|
+
hookup { topic.lowercase_word }
|
235
|
+
|
236
|
+
asserts(:pos).equals "foo bar".size
|
237
|
+
asserts(:line).equals "foo bar"
|
238
|
+
end
|
239
|
+
|
240
|
+
context "after uppercasing word" do
|
241
|
+
hookup { topic.uppercase_word }
|
242
|
+
|
243
|
+
asserts(:pos).equals "bar foo".size
|
244
|
+
asserts(:line).equals "foo BAR"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context "editor between two out of three words" do
|
249
|
+
setup { Editor.new("foo bar baz", 7) }
|
250
|
+
|
251
|
+
context "after inserting a word" do
|
252
|
+
hookup { topic.insert_string "wow" }
|
253
|
+
|
254
|
+
asserts(:pos).equals 10
|
255
|
+
asserts(:line).equals "foo barwow baz"
|
256
|
+
end
|
257
|
+
|
258
|
+
context "after killing previous word" do
|
259
|
+
hookup { topic.kill_backward_word }
|
260
|
+
|
261
|
+
asserts(:pos).equals 4
|
262
|
+
asserts(:line).equals "foo baz"
|
263
|
+
end
|
264
|
+
|
265
|
+
context "after killing previous character" do
|
266
|
+
hookup { topic.kill_backward_char }
|
267
|
+
|
268
|
+
asserts(:pos).equals 6
|
269
|
+
asserts(:line).equals "foo ba baz"
|
270
|
+
end
|
271
|
+
|
272
|
+
context "after killing current character" do
|
273
|
+
hookup { topic.kill_current_char }
|
274
|
+
|
275
|
+
asserts(:pos).equals 7
|
276
|
+
asserts(:line).equals "foo barbaz"
|
277
|
+
end
|
278
|
+
|
279
|
+
context "after moving to the next character" do
|
280
|
+
hookup { topic.forward_char }
|
281
|
+
|
282
|
+
asserts(:pos).equals 8
|
283
|
+
asserts(:line).equals "foo bar baz"
|
284
|
+
end
|
285
|
+
|
286
|
+
context "after moving to the previous character" do
|
287
|
+
hookup { topic.backward_char }
|
288
|
+
|
289
|
+
asserts(:pos).equals 6
|
290
|
+
asserts(:line).equals "foo bar baz"
|
291
|
+
end
|
292
|
+
|
293
|
+
context "after transposing characters" do
|
294
|
+
hookup { topic.transpose_chars }
|
295
|
+
|
296
|
+
asserts(:pos).equals 8
|
297
|
+
asserts(:line).equals "foo ba rbaz"
|
298
|
+
end
|
299
|
+
|
300
|
+
context "after moving one word backward" do
|
301
|
+
hookup { topic.backward_word }
|
302
|
+
|
303
|
+
asserts(:pos).equals 4
|
304
|
+
asserts(:line).equals "foo bar baz"
|
305
|
+
end
|
306
|
+
|
307
|
+
context "after moving one word forward" do
|
308
|
+
hookup { topic.forward_word }
|
309
|
+
|
310
|
+
asserts(:pos).equals "foo bar baz".size
|
311
|
+
asserts(:line).equals "foo bar baz"
|
312
|
+
end
|
313
|
+
|
314
|
+
context "after killing the end of the line" do
|
315
|
+
hookup { topic.kill_line }
|
316
|
+
|
317
|
+
asserts(:pos).equals 7
|
318
|
+
asserts(:line).equals "foo bar"
|
319
|
+
end
|
320
|
+
|
321
|
+
context "after transposing words" do
|
322
|
+
hookup { topic.transpose_words }
|
323
|
+
|
324
|
+
asserts(:pos).equals "foo bar baz".size
|
325
|
+
asserts(:line).equals "foo baz bar"
|
326
|
+
end
|
327
|
+
|
328
|
+
context "after capitalizing word" do
|
329
|
+
hookup { topic.capitalize_word }
|
330
|
+
|
331
|
+
asserts(:pos).equals "foo bar baz".size
|
332
|
+
asserts(:line).equals "foo bar Baz"
|
333
|
+
end
|
334
|
+
|
335
|
+
context "after lowercasing word" do
|
336
|
+
hookup { topic.lowercase_word }
|
337
|
+
|
338
|
+
asserts(:pos).equals "foo bar baz".size
|
339
|
+
asserts(:line).equals "foo bar baz"
|
340
|
+
end
|
341
|
+
|
342
|
+
context "after uppercasing word" do
|
343
|
+
hookup { topic.uppercase_word }
|
344
|
+
|
345
|
+
asserts(:pos).equals "bar foo baz".size
|
346
|
+
asserts(:line).equals "foo bar BAZ"
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
context "editor at the end of a line" do
|
351
|
+
setup { Editor.new(str = "a lovely dragon", str.size) }
|
352
|
+
|
353
|
+
context "after inserting a word" do
|
354
|
+
hookup { topic.insert_string " here" }
|
355
|
+
|
356
|
+
asserts(:pos).equals "a lovely dragon here".size
|
357
|
+
asserts(:line).equals "a lovely dragon here"
|
358
|
+
end
|
359
|
+
|
360
|
+
context "after killing previous word" do
|
361
|
+
hookup { topic.kill_backward_word }
|
362
|
+
|
363
|
+
asserts(:pos).equals "a lovely ".size
|
364
|
+
asserts(:line).equals "a lovely "
|
365
|
+
end
|
366
|
+
|
367
|
+
context "after going to the beginning of the line" do
|
368
|
+
hookup { topic.beginning_of_line }
|
369
|
+
asserts(:pos).equals 0
|
370
|
+
end
|
371
|
+
|
372
|
+
context "after killing previous character" do
|
373
|
+
hookup { topic.kill_backward_char }
|
374
|
+
|
375
|
+
asserts(:pos).equals("a lovely dragon".size - 1)
|
376
|
+
asserts(:line).equals "a lovely drago"
|
377
|
+
end
|
378
|
+
|
379
|
+
context "after killing current character" do
|
380
|
+
hookup { topic.kill_current_char }
|
381
|
+
|
382
|
+
asserts(:pos).equals "a lovely dragon".size
|
383
|
+
asserts(:line).equals "a lovely dragon"
|
384
|
+
end
|
385
|
+
|
386
|
+
context "after moving to the next character" do
|
387
|
+
hookup { topic.forward_char }
|
388
|
+
|
389
|
+
asserts(:pos).equals "a lovely dragon".size
|
390
|
+
asserts(:line).equals "a lovely dragon"
|
391
|
+
end
|
392
|
+
|
393
|
+
context "after moving to the previous character" do
|
394
|
+
hookup { topic.backward_char }
|
395
|
+
|
396
|
+
asserts(:pos).equals "a lovely dragon".size - 1
|
397
|
+
asserts(:line).equals "a lovely dragon"
|
398
|
+
end
|
399
|
+
|
400
|
+
context "after transposing characters" do
|
401
|
+
hookup { topic.transpose_chars }
|
402
|
+
|
403
|
+
asserts(:pos).equals "a lovely dragon".size
|
404
|
+
asserts(:line).equals "a lovely dragno"
|
405
|
+
end
|
406
|
+
|
407
|
+
context "after moving one word backward" do
|
408
|
+
hookup { topic.backward_word }
|
409
|
+
|
410
|
+
asserts(:pos).equals "a lovely ".size
|
411
|
+
asserts(:line).equals "a lovely dragon"
|
412
|
+
end
|
413
|
+
|
414
|
+
context "after moving one word forward" do
|
415
|
+
hookup { topic.forward_word }
|
416
|
+
|
417
|
+
asserts(:pos).equals "a lovely dragon".size
|
418
|
+
asserts(:line).equals "a lovely dragon"
|
419
|
+
end
|
420
|
+
|
421
|
+
context "after killing the end of the line" do
|
422
|
+
hookup { topic.kill_line }
|
423
|
+
|
424
|
+
asserts(:pos).equals "a lovely dragon".size
|
425
|
+
asserts(:line).equals "a lovely dragon"
|
426
|
+
end
|
427
|
+
|
428
|
+
context "after transposing words" do
|
429
|
+
hookup { topic.transpose_words }
|
430
|
+
|
431
|
+
asserts(:pos).equals "a lovely dragon".size
|
432
|
+
asserts(:line).equals "a dragon lovely"
|
433
|
+
end
|
434
|
+
|
435
|
+
context "after capitalizing word" do
|
436
|
+
hookup { topic.capitalize_word }
|
437
|
+
|
438
|
+
asserts(:pos).equals "a lovely dragon".size
|
439
|
+
asserts(:line).equals "a lovely dragon"
|
440
|
+
end
|
441
|
+
|
442
|
+
context "after lowercasing word" do
|
443
|
+
hookup { topic.lowercase_word }
|
444
|
+
|
445
|
+
asserts(:pos).equals "a lovely dragon".size
|
446
|
+
asserts(:line).equals "a lovely dragon"
|
447
|
+
end
|
448
|
+
|
449
|
+
context "after uppercasing word" do
|
450
|
+
hookup { topic.uppercase_word }
|
451
|
+
|
452
|
+
asserts(:pos).equals "a lovely dragon".size
|
453
|
+
asserts(:line).equals "a lovely dragon"
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
context "editor in the middle of a sentence" do
|
458
|
+
setup { Editor.new("foo bar baz qux", 8) }
|
459
|
+
|
460
|
+
context "after inserting a word" do
|
461
|
+
hookup { topic.insert_string "at" }
|
462
|
+
|
463
|
+
asserts(:pos).equals 10
|
464
|
+
asserts(:line).equals "foo bar atbaz qux"
|
465
|
+
end
|
466
|
+
|
467
|
+
context "after killing previous word" do
|
468
|
+
hookup { topic.kill_backward_word }
|
469
|
+
|
470
|
+
asserts(:pos).equals 4
|
471
|
+
asserts(:line).equals "foo baz qux"
|
472
|
+
end
|
473
|
+
|
474
|
+
context "after going to the beginning of the line" do
|
475
|
+
hookup { topic.beginning_of_line }
|
476
|
+
asserts(:pos).equals 0
|
477
|
+
end
|
478
|
+
|
479
|
+
context "after going to the end of the line" do
|
480
|
+
hookup { topic.end_of_line }
|
481
|
+
asserts(:pos).equals "foo bar baz qux".size
|
482
|
+
end
|
483
|
+
|
484
|
+
context "after killing previous character" do
|
485
|
+
hookup { topic.kill_backward_char }
|
486
|
+
|
487
|
+
asserts(:pos).equals 7
|
488
|
+
asserts(:line).equals "foo barbaz qux"
|
489
|
+
end
|
490
|
+
|
491
|
+
context "after killing current character" do
|
492
|
+
hookup { topic.kill_current_char }
|
493
|
+
|
494
|
+
asserts(:pos).equals 8
|
495
|
+
asserts(:line).equals "foo bar az qux"
|
496
|
+
end
|
497
|
+
|
498
|
+
context "after moving to the next character" do
|
499
|
+
hookup { topic.forward_char }
|
500
|
+
|
501
|
+
asserts(:pos).equals 9
|
502
|
+
asserts(:line).equals "foo bar baz qux"
|
503
|
+
end
|
504
|
+
|
505
|
+
context "after moving to the previous character" do
|
506
|
+
hookup { topic.backward_char }
|
507
|
+
|
508
|
+
asserts(:pos).equals 7
|
509
|
+
asserts(:line).equals "foo bar baz qux"
|
510
|
+
end
|
511
|
+
|
512
|
+
context "after transposing characters" do
|
513
|
+
hookup { topic.transpose_chars }
|
514
|
+
|
515
|
+
asserts(:pos).equals 9
|
516
|
+
asserts(:line).equals "foo barb az qux"
|
517
|
+
end
|
518
|
+
|
519
|
+
context "after moving one word backward" do
|
520
|
+
hookup { topic.backward_word }
|
521
|
+
|
522
|
+
asserts(:pos).equals 4
|
523
|
+
asserts(:line).equals "foo bar baz qux"
|
524
|
+
end
|
525
|
+
|
526
|
+
context "after moving one word forward" do
|
527
|
+
hookup { topic.forward_word }
|
528
|
+
|
529
|
+
asserts(:pos).equals 11
|
530
|
+
asserts(:line).equals "foo bar baz qux"
|
531
|
+
end
|
532
|
+
|
533
|
+
context "after killing the end of the line" do
|
534
|
+
hookup { topic.kill_line }
|
535
|
+
|
536
|
+
asserts(:pos).equals 8
|
537
|
+
asserts(:line).equals "foo bar "
|
538
|
+
end
|
539
|
+
|
540
|
+
context "after transposing words" do
|
541
|
+
hookup { topic.transpose_words }
|
542
|
+
|
543
|
+
asserts(:pos).equals 11
|
544
|
+
asserts(:line).equals "foo baz bar qux"
|
545
|
+
end
|
546
|
+
|
547
|
+
context "after capitalizing word" do
|
548
|
+
hookup { topic.capitalize_word }
|
549
|
+
|
550
|
+
asserts(:pos).equals "foo bar baz".size
|
551
|
+
asserts(:line).equals "foo bar Baz qux"
|
552
|
+
end
|
553
|
+
|
554
|
+
context "after lowercasing word" do
|
555
|
+
hookup { topic.lowercase_word }
|
556
|
+
|
557
|
+
asserts(:pos).equals "foo bar baz".size
|
558
|
+
asserts(:line).equals "foo bar baz qux"
|
559
|
+
end
|
560
|
+
|
561
|
+
context "after uppercasing word" do
|
562
|
+
hookup { topic.uppercase_word }
|
563
|
+
|
564
|
+
asserts(:pos).equals "foo bar baz".size
|
565
|
+
asserts(:line).equals "foo bar BAZ qux"
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
context "editor in the middle of a word" do
|
570
|
+
setup { Editor.new("foo bar baz qux", 9) }
|
571
|
+
|
572
|
+
context "after inserting a word" do
|
573
|
+
hookup { topic.insert_string "at" }
|
574
|
+
|
575
|
+
asserts(:pos).equals 11
|
576
|
+
asserts(:line).equals "foo bar bataz qux"
|
577
|
+
end
|
578
|
+
|
579
|
+
context "after killing previous word" do
|
580
|
+
hookup { topic.kill_backward_word }
|
581
|
+
|
582
|
+
asserts(:pos).equals 8
|
583
|
+
asserts(:line).equals "foo bar az qux"
|
584
|
+
end
|
585
|
+
|
586
|
+
context "after going to the beginning of the line" do
|
587
|
+
hookup { topic.beginning_of_line }
|
588
|
+
asserts(:pos).equals 0
|
589
|
+
end
|
590
|
+
|
591
|
+
context "after going to the end of the line" do
|
592
|
+
hookup { topic.end_of_line }
|
593
|
+
asserts(:pos).equals "foo bar baz qux".size
|
594
|
+
end
|
595
|
+
|
596
|
+
context "after killing previous character" do
|
597
|
+
hookup { topic.kill_backward_char }
|
598
|
+
|
599
|
+
asserts(:pos).equals 8
|
600
|
+
asserts(:line).equals "foo bar az qux"
|
601
|
+
end
|
602
|
+
|
603
|
+
context "after killing current character" do
|
604
|
+
hookup { topic.kill_current_char }
|
605
|
+
|
606
|
+
asserts(:pos).equals 9
|
607
|
+
asserts(:line).equals "foo bar bz qux"
|
608
|
+
end
|
609
|
+
|
610
|
+
context "after moving to the next character" do
|
611
|
+
hookup { topic.forward_char }
|
612
|
+
|
613
|
+
asserts(:pos).equals 10
|
614
|
+
asserts(:line).equals "foo bar baz qux"
|
615
|
+
end
|
616
|
+
|
617
|
+
context "after moving to the previous character" do
|
618
|
+
hookup { topic.backward_char }
|
619
|
+
|
620
|
+
asserts(:pos).equals 8
|
621
|
+
asserts(:line).equals "foo bar baz qux"
|
622
|
+
end
|
623
|
+
|
624
|
+
context "after transposing characters" do
|
625
|
+
hookup { topic.transpose_chars }
|
626
|
+
|
627
|
+
asserts(:pos).equals 10
|
628
|
+
asserts(:line).equals "foo bar abz qux"
|
629
|
+
end
|
630
|
+
|
631
|
+
context "after moving one word backward" do
|
632
|
+
hookup { topic.backward_word }
|
633
|
+
|
634
|
+
asserts(:pos).equals 8
|
635
|
+
asserts(:line).equals "foo bar baz qux"
|
636
|
+
end
|
637
|
+
|
638
|
+
context "after moving one word forward" do
|
639
|
+
hookup { topic.forward_word }
|
640
|
+
|
641
|
+
asserts(:pos).equals 11
|
642
|
+
asserts(:line).equals "foo bar baz qux"
|
643
|
+
end
|
644
|
+
|
645
|
+
context "after killing the end of the line" do
|
646
|
+
hookup { topic.kill_line }
|
647
|
+
|
648
|
+
asserts(:pos).equals 9
|
649
|
+
asserts(:line).equals "foo bar b"
|
650
|
+
end
|
651
|
+
|
652
|
+
context "after transposing words" do
|
653
|
+
hookup { topic.transpose_words }
|
654
|
+
|
655
|
+
asserts(:pos).equals 11
|
656
|
+
asserts(:line).equals "foo baz bar qux"
|
657
|
+
end
|
658
|
+
|
659
|
+
context "after capitalizing word" do
|
660
|
+
hookup { topic.capitalize_word }
|
661
|
+
|
662
|
+
asserts(:pos).equals "foo bar baz".size
|
663
|
+
asserts(:line).equals "foo bar bAz qux"
|
664
|
+
end
|
665
|
+
|
666
|
+
context "after lowercasing word" do
|
667
|
+
hookup { topic.lowercase_word }
|
668
|
+
|
669
|
+
asserts(:pos).equals "foo bar baz".size
|
670
|
+
asserts(:line).equals "foo bar baz qux"
|
671
|
+
end
|
672
|
+
|
673
|
+
context "after uppercasing word" do
|
674
|
+
hookup { topic.uppercase_word }
|
675
|
+
|
676
|
+
asserts(:pos).equals "foo bar baz".size
|
677
|
+
asserts(:line).equals "foo bar bAZ qux"
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
context "editor at the end of a line with trailing whitespaces" do
|
682
|
+
setup { Editor.new("a dragon ", 9) }
|
683
|
+
|
684
|
+
context "after transposing words" do
|
685
|
+
hookup { topic.transpose_words }
|
686
|
+
|
687
|
+
asserts(:pos).equals 8
|
688
|
+
asserts(:line).equals "dragon a "
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
context "editor at the end of a one-word line with trailing whitespaces" do
|
693
|
+
setup { Editor.new("dragon ", 7) }
|
694
|
+
|
695
|
+
context "after transposing words" do
|
696
|
+
hookup { topic.transpose_words }
|
697
|
+
|
698
|
+
asserts(:pos).equals 7
|
699
|
+
asserts(:line).equals "dragon "
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
context "an editor in a mixed case word" do
|
704
|
+
str = "Elite_cOdEr"
|
705
|
+
setup { Editor.new(str, 3) }
|
706
|
+
|
707
|
+
context "after capitalizing word" do
|
708
|
+
hookup { topic.capitalize_word }
|
709
|
+
|
710
|
+
asserts(:pos).equals str.size
|
711
|
+
asserts(:line).equals "EliTe_coder"
|
712
|
+
end
|
713
|
+
|
714
|
+
context "after lowercasing word" do
|
715
|
+
hookup { topic.lowercase_word }
|
716
|
+
|
717
|
+
asserts(:pos).equals str.size
|
718
|
+
asserts(:line).equals "Elite_coder"
|
719
|
+
end
|
720
|
+
|
721
|
+
context "after uppercasing word" do
|
722
|
+
hookup { topic.uppercase_word }
|
723
|
+
|
724
|
+
asserts(:pos).equals str.size
|
725
|
+
asserts(:line).equals "EliTE_CODER"
|
726
|
+
end
|
727
|
+
end
|