coolline 0.0.1pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,3 @@
1
+ class Coolline
2
+ Version = "0.0.1pre"
3
+ 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
@@ -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