dietrb 0.4.7 → 0.5.0
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/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
|