dietrb 0.4.7 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +11 -5
- data/Rakefile +13 -9
- data/TODO +1 -0
- data/bin/dietrb +49 -35
- data/dietrb.gemspec +21 -11
- data/lib/irb.rb +0 -3
- data/lib/irb/completion.rb +1 -1
- data/lib/irb/context.rb +21 -58
- data/lib/irb/driver.rb +61 -0
- data/lib/irb/driver/readline.rb +26 -0
- data/lib/irb/driver/socket.rb +44 -0
- data/lib/irb/driver/tty.rb +58 -0
- data/lib/irb/ext/completion.rb +13 -12
- data/lib/irb/ext/history.rb +53 -58
- data/lib/irb/formatter.rb +3 -1
- data/lib/irb/version.rb +2 -2
- data/spec/context_spec.rb +29 -107
- data/spec/driver/readline_spec.rb +70 -0
- data/spec/driver/tty_spec.rb +70 -0
- data/spec/driver_spec.rb +65 -0
- data/spec/{colorize_spec.rb → ext/colorize_spec.rb} +1 -1
- data/spec/{completion_spec.rb → ext/completion_spec.rb} +12 -8
- data/spec/{history_spec.rb → ext/history_spec.rb} +42 -45
- data/spec/formatter_spec.rb +5 -3
- data/spec/regression/context_spec.rb +1 -1
- data/spec/source_spec.rb +25 -29
- data/spec/spec_helper.rb +69 -5
- metadata +21 -24
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
2
|
+
require "irb/driver/readline"
|
3
|
+
|
4
|
+
module Readline
|
5
|
+
extend InputStubMixin
|
6
|
+
extend OutputStubMixin
|
7
|
+
|
8
|
+
def self.input=(input)
|
9
|
+
@given_input = input
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.given_input
|
13
|
+
@given_input
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.output=(output)
|
17
|
+
@given_output = output
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.given_output
|
21
|
+
@given_output
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.use_history=(use_history)
|
25
|
+
@use_history = use_history
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.use_history
|
29
|
+
@use_history
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.readline(prompt, use_history)
|
33
|
+
@use_history = use_history
|
34
|
+
print prompt
|
35
|
+
@input.shift
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "IRB::Driver::Readline" do
|
40
|
+
before do
|
41
|
+
@driver = IRB::Driver::Readline.new(InputStub.new, OutputStub.new)
|
42
|
+
@context = IRB::Context.new(Object.new)
|
43
|
+
@driver.context_stack << @context
|
44
|
+
end
|
45
|
+
|
46
|
+
it "is a subclass of IRB::Driver::TTY" do
|
47
|
+
IRB::Driver::Readline.superclass.should == IRB::Driver::TTY
|
48
|
+
end
|
49
|
+
|
50
|
+
it "assigns the given input and output to the Readline module" do
|
51
|
+
Readline.given_input.should == @driver.input
|
52
|
+
Readline.given_output.should == @driver.output
|
53
|
+
end
|
54
|
+
|
55
|
+
it "assigns a completion object" do
|
56
|
+
Readline.completion_proc.class.should == IRB::Completion
|
57
|
+
end
|
58
|
+
|
59
|
+
it "reads a line through the Readline module" do
|
60
|
+
Readline.stub_input "nom nom nom"
|
61
|
+
@driver.readline.should == "nom nom nom"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "tells the Readline module to use the history" do
|
65
|
+
Readline.use_history = false
|
66
|
+
Readline.stub_input "nom nom nom"
|
67
|
+
@driver.readline
|
68
|
+
Readline.use_history.should == true
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'irb/driver/tty'
|
3
|
+
|
4
|
+
describe "IRB::Driver::TTY" do
|
5
|
+
before do
|
6
|
+
@driver = IRB::Driver::TTY.new(InputStub.new, OutputStub.new)
|
7
|
+
@context = IRB::Context.new(Object.new)
|
8
|
+
@driver.context_stack << @context
|
9
|
+
end
|
10
|
+
|
11
|
+
it "prints the prompt and reads a line of input" do
|
12
|
+
@driver.input.stub_input "calzone"
|
13
|
+
@driver.readline.should == "calzone"
|
14
|
+
@driver.output.printed.should == @context.prompt
|
15
|
+
end
|
16
|
+
|
17
|
+
it "consumes input" do
|
18
|
+
@driver.input.stub_input "calzone"
|
19
|
+
@driver.consume.should == "calzone"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "clears the context buffer if an Interrupt signal is received while consuming input" do
|
23
|
+
@context.process_line("class A")
|
24
|
+
def @driver.readline; raise Interrupt; end
|
25
|
+
@driver.consume.should == ""
|
26
|
+
@context.source.to_s.should == ""
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "IRB::Driver::TTY, when starting the runloop" do
|
31
|
+
before do
|
32
|
+
@driver = IRB::Driver::TTY.new(InputStub.new, OutputStub.new)
|
33
|
+
IRB::Driver.current = @driver
|
34
|
+
@context = IRB::Context.new(Object.new)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "makes the given context the current one, for this driver, for the duration of the runloop" do
|
38
|
+
$from_context = nil
|
39
|
+
@driver.input.stub_input "$from_context = IRB::Driver.current.context"
|
40
|
+
@driver.run(@context)
|
41
|
+
$from_context.should == @context
|
42
|
+
IRB::Driver.current.context.should == nil
|
43
|
+
end
|
44
|
+
|
45
|
+
it "feeds input into a given context" do
|
46
|
+
$from_context = false
|
47
|
+
@driver.input.stub_input "$from_context = true", "exit"
|
48
|
+
@driver.run(@context)
|
49
|
+
$from_context.should == true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "makes sure there's a global output redirector while running a context" do
|
53
|
+
before = $stdout
|
54
|
+
$from_context = nil
|
55
|
+
@driver.input.stub_input "$from_context = $stdout", "exit"
|
56
|
+
@driver.run(@context)
|
57
|
+
$from_context.class == IRB::Driver::OutputRedirector
|
58
|
+
$stdout.should == before
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# describe "Kernel::irb" do
|
63
|
+
# it "creates a new context for the given object and runs it" do
|
64
|
+
# IRB.io = CaptureIO.new
|
65
|
+
# IRB.io.stub_input("::IRBRan = self")
|
66
|
+
# o = Object.new
|
67
|
+
# irb(o)
|
68
|
+
# IRBRan.should == o
|
69
|
+
# end
|
70
|
+
# end
|
data/spec/driver_spec.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
require 'irb/driver'
|
3
|
+
|
4
|
+
describe "IRB::Driver" do
|
5
|
+
before :all do
|
6
|
+
@driver = StubDriver.new
|
7
|
+
IRB::Driver.current = @driver
|
8
|
+
end
|
9
|
+
|
10
|
+
it "assigns the driver for the current thread" do
|
11
|
+
Thread.current[:irb_driver].should == @driver
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns the same driver for child threads" do
|
15
|
+
Thread.new do
|
16
|
+
IRB::Driver.current = other = StubDriver.new
|
17
|
+
Thread.new { IRB::Driver.current.should == other }.join
|
18
|
+
end.join
|
19
|
+
Thread.new { IRB::Driver.current.should == @driver }.join
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "IRB::Driver::OutputRedirector" do
|
24
|
+
before :each do
|
25
|
+
@driver = StubDriver.new
|
26
|
+
@driver.output = OutputStub.new
|
27
|
+
IRB::Driver.current = @driver
|
28
|
+
|
29
|
+
@redirector = IRB::Driver::OutputRedirector.new
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns $stderr as the target if no current driver could be found" do
|
33
|
+
IRB::Driver.current = nil
|
34
|
+
IRB::Driver::OutputRedirector.target.should == $stderr
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns the current driver's output as the target" do
|
38
|
+
IRB::Driver::OutputRedirector.target.should == @driver.output
|
39
|
+
end
|
40
|
+
|
41
|
+
it "forwards method calls to the current target" do
|
42
|
+
@redirector.send_to_target(:eql?, @driver.output).should == true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "writes to the current target's output" do
|
46
|
+
@redirector.write("strawberry coupe")
|
47
|
+
@driver.output.printed.should == "strawberry coupe"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns the amount of bytes written" do
|
51
|
+
@redirector.write("banana coupe").should == 12
|
52
|
+
end
|
53
|
+
|
54
|
+
it "coerces an object to a string before writing" do
|
55
|
+
o = Object.new
|
56
|
+
def o.to_s; "cherry coupe"; end
|
57
|
+
@redirector.write(o)
|
58
|
+
@driver.output.printed.should == "cherry coupe"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "forwards puts to the current target's output" do
|
62
|
+
@redirector.puts("double", "coupe")
|
63
|
+
@driver.output.printed.should == "double\ncoupe\n"
|
64
|
+
end
|
65
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
|
-
require File.expand_path('
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'irb/driver'
|
2
3
|
require 'irb/ext/completion'
|
3
4
|
|
4
5
|
module CompletionHelper
|
5
6
|
def complete(str)
|
6
|
-
IRB::Completion.new(@context, str).results
|
7
|
+
# IRB::Completion.new(@context, str).results
|
8
|
+
@completion.call(str)
|
7
9
|
end
|
8
10
|
|
9
11
|
def imethods(klass, receiver = nil)
|
@@ -15,8 +17,6 @@ module CompletionHelper
|
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
|
-
Bacon::Context.send(:include, CompletionHelper)
|
19
|
-
|
20
20
|
class CompletionStub
|
21
21
|
def self.a_cmethod
|
22
22
|
end
|
@@ -35,12 +35,16 @@ end
|
|
35
35
|
$a_completion_stub = CompletionStub.new
|
36
36
|
|
37
37
|
describe "IRB::Completion" do
|
38
|
-
|
38
|
+
extend CompletionHelper
|
39
|
+
|
40
|
+
before :all do
|
41
|
+
@completion = IRB::Completion.new
|
39
42
|
@context = IRB::Context.new(Playground.new)
|
43
|
+
IRB::Driver.current = StubDriver.new(@context)
|
40
44
|
end
|
41
45
|
|
42
46
|
it "quacks like a Proc" do
|
43
|
-
|
47
|
+
@completion.call('//.').should == imethods(Regexp, '//')
|
44
48
|
end
|
45
49
|
|
46
50
|
describe "when doing a method call on an explicit receiver," do
|
@@ -51,7 +55,7 @@ describe "IRB::Completion" do
|
|
51
55
|
complete('foo.').should == imethods(::CompletionStub, 'foo')
|
52
56
|
|
53
57
|
@context.__evaluate__('def foo.singleton_method; end')
|
54
|
-
complete('foo.').should
|
58
|
+
complete('foo.').should include('foo.singleton_method')
|
55
59
|
end
|
56
60
|
|
57
61
|
it "matches as a global variable" do
|
@@ -231,7 +235,7 @@ describe "IRB::Completion" do
|
|
231
235
|
it "completes reserved words as variables or constants" do
|
232
236
|
(IRB::Completion::RESERVED_DOWNCASE_WORDS +
|
233
237
|
IRB::Completion::RESERVED_UPCASE_WORDS).each do |word|
|
234
|
-
complete(word[0..-2]).should
|
238
|
+
complete(word[0..-2]).should include(word)
|
235
239
|
end
|
236
240
|
end
|
237
241
|
end
|
@@ -1,15 +1,21 @@
|
|
1
|
-
require File.expand_path('
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
require 'readline'
|
2
3
|
require "tempfile"
|
3
4
|
|
4
|
-
|
5
|
-
|
5
|
+
require 'irb/ext/history'
|
6
|
+
require 'irb/driver'
|
7
|
+
|
8
|
+
describe "IRB::History, by default," do
|
9
|
+
it "stores the history in ~/.irb_history" do
|
6
10
|
IRB::History.file.should == File.expand_path("~/.irb_history")
|
7
11
|
end
|
8
|
-
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "IRB::History" do
|
9
15
|
before do
|
10
16
|
@file = Tempfile.new("irb_history.txt")
|
11
17
|
IRB::History.file = @file.path
|
12
|
-
@history = IRB::History
|
18
|
+
@history = IRB::History
|
13
19
|
end
|
14
20
|
|
15
21
|
after do
|
@@ -39,10 +45,10 @@ describe "IRB::History" do
|
|
39
45
|
FileUtils.rm(@file.path)
|
40
46
|
|
41
47
|
@history.to_a.should == []
|
42
|
-
File.
|
48
|
+
File.exist?(@file.path).should == false
|
43
49
|
|
44
50
|
@history.input "puts :ok"
|
45
|
-
File.
|
51
|
+
File.exist?(@file.path).should == true
|
46
52
|
@history.to_a.should == ["puts :ok"]
|
47
53
|
end
|
48
54
|
|
@@ -52,8 +58,8 @@ describe "IRB::History" do
|
|
52
58
|
@history.input "puts :ok"
|
53
59
|
@history.input "foo(x)"
|
54
60
|
|
55
|
-
IRB::History.
|
56
|
-
IRB::History.
|
61
|
+
IRB::History.setup
|
62
|
+
IRB::History.setup
|
57
63
|
|
58
64
|
Readline::HISTORY.to_a.should == ["puts :ok", "foo(x)"]
|
59
65
|
end
|
@@ -63,37 +69,30 @@ describe "IRB::History" do
|
|
63
69
|
@history.input "foo(x)"
|
64
70
|
@history.clear!
|
65
71
|
|
66
|
-
@file.rewind; @file.read.should
|
67
|
-
Readline::HISTORY.to_a.should
|
72
|
+
@file.rewind; @file.read.should == ""
|
73
|
+
Readline::HISTORY.to_a.should == []
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
def puts(s)
|
81
|
-
printed << "#{s}\n"
|
82
|
-
end
|
83
|
-
|
84
|
-
def clear!
|
85
|
-
@cleared = true
|
86
|
-
end
|
87
|
-
def cleared?
|
88
|
-
@cleared
|
77
|
+
module IRB::History
|
78
|
+
class << self
|
79
|
+
def clear!
|
80
|
+
@cleared = true
|
81
|
+
end
|
82
|
+
|
83
|
+
def cleared?
|
84
|
+
@cleared
|
85
|
+
end
|
89
86
|
end
|
90
87
|
end
|
91
88
|
|
92
|
-
describe "IRB::History, concerning the user api" do
|
93
|
-
it "shows
|
89
|
+
describe "IRB::History, concerning the user api, by default," do
|
90
|
+
it "shows a maximum of 50 history entries" do
|
94
91
|
IRB::History.max_entries_in_overview.should == 50
|
95
92
|
end
|
96
|
-
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "IRB::History, concerning the user api," do
|
97
96
|
before do
|
98
97
|
sources = [
|
99
98
|
"puts :ok",
|
@@ -111,24 +110,22 @@ describe "IRB::History, concerning the user api" do
|
|
111
110
|
|
112
111
|
IRB::History.max_entries_in_overview = 5
|
113
112
|
|
114
|
-
|
115
|
-
IRB::
|
113
|
+
IRB::History.extend(OutputStubMixin)
|
114
|
+
IRB::History.clear_printed!
|
116
115
|
|
117
|
-
@
|
118
|
-
|
119
|
-
|
120
|
-
after do
|
121
|
-
IRB::Context.current = nil
|
116
|
+
@context = IRB::Context.new(Object.new)
|
117
|
+
@context.extend(OutputStubMixin)
|
118
|
+
IRB::Driver.current = StubDriver.new(@context)
|
122
119
|
end
|
123
120
|
|
124
121
|
it "returns nil so that IRB doesn't cache some arbitrary line number" do
|
125
|
-
history.should ==
|
122
|
+
history.should == IRB::Context::IGNORE_RESULT
|
126
123
|
end
|
127
124
|
|
128
|
-
it "prints a formatted list with
|
125
|
+
it "prints a formatted list with IRB::History.max_entries_in_overview number of history entries" do
|
129
126
|
history
|
130
127
|
|
131
|
-
|
128
|
+
IRB::History.printed.should == %{
|
132
129
|
2: class AAA
|
133
130
|
3: def bar
|
134
131
|
4: :ok
|
@@ -140,7 +137,7 @@ describe "IRB::History, concerning the user api" do
|
|
140
137
|
it "prints a formatted list of N most recent history entries" do
|
141
138
|
history(7)
|
142
139
|
|
143
|
-
|
140
|
+
IRB::History.printed.should == %{
|
144
141
|
0: puts :ok
|
145
142
|
1: x = foo(x)
|
146
143
|
2: class AAA
|
@@ -154,7 +151,7 @@ describe "IRB::History, concerning the user api" do
|
|
154
151
|
it "prints a formatted list of all history entries if the request number of entries is more than there is" do
|
155
152
|
history(777)
|
156
153
|
|
157
|
-
|
154
|
+
IRB::History.printed.should == %{
|
158
155
|
0: puts :ok
|
159
156
|
1: x = foo(x)
|
160
157
|
2: class AAA
|
@@ -178,6 +175,6 @@ describe "IRB::History, concerning the user api" do
|
|
178
175
|
|
179
176
|
it "clears the history and history file" do
|
180
177
|
clear_history!
|
181
|
-
|
178
|
+
IRB::History.cleared?.should == true
|
182
179
|
end
|
183
180
|
end
|
data/spec/formatter_spec.rb
CHANGED
@@ -40,13 +40,15 @@ describe "IRB::Formatter" do
|
|
40
40
|
|
41
41
|
it "does not filter the backtrace if $DEBUG is true" do
|
42
42
|
begin
|
43
|
-
|
43
|
+
stderr, $stderr = $stderr, OutputStub.new
|
44
|
+
debug, $DEBUG = $DEBUG, true
|
44
45
|
|
45
46
|
begin; @context.__evaluate__('DoesNotExist'); rescue NameError => e; exception = e; end
|
46
47
|
@formatter.exception(exception).should ==
|
47
48
|
"NameError: uninitialized constant IRB::Context::DoesNotExist\n\t#{exception.backtrace.join("\n\t")}"
|
48
49
|
ensure
|
49
|
-
$
|
50
|
+
$stderr = stderr
|
51
|
+
$DEBUG = debug
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
@@ -68,7 +70,7 @@ describe "IRB::Formatter" do
|
|
68
70
|
def object.__id__; 2158110700; end
|
69
71
|
|
70
72
|
@formatter.result(object).should == "=> #<Object:0x101444fd8>"
|
71
|
-
object.instance_variable_get(:@inspected).
|
73
|
+
object.instance_variable_get(:@inspected).should_not == true
|
72
74
|
end
|
73
75
|
|
74
76
|
it "prints that a syntax error occurred on the last line and reset the buffer to the previous line" do
|