iruby 0.5.0 → 0.7.2
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.
- checksums.yaml +4 -4
- data/.github/workflows/ubuntu.yml +9 -2
- data/CHANGES.md +226 -0
- data/README.md +17 -2
- data/iruby.gemspec +1 -1
- data/lib/iruby.rb +4 -0
- data/lib/iruby/backend.rb +32 -7
- data/lib/iruby/command.rb +2 -6
- data/lib/iruby/display.rb +178 -59
- data/lib/iruby/event_manager.rb +40 -0
- data/lib/iruby/kernel.rb +139 -16
- data/lib/iruby/ostream.rb +5 -0
- data/lib/iruby/session.rb +1 -0
- data/lib/iruby/session_adapter.rb +6 -0
- data/lib/iruby/session_adapter/test_adapter.rb +49 -0
- data/lib/iruby/utils.rb +12 -1
- data/lib/iruby/version.rb +1 -1
- data/test/helper.rb +46 -0
- data/test/iruby/backend_test.rb +12 -0
- data/test/iruby/display_test.rb +188 -0
- data/test/iruby/event_manager_test.rb +92 -0
- data/test/iruby/kernel_test.rb +185 -0
- data/test/iruby/mime_test.rb +25 -7
- data/test/iruby/multi_logger_test.rb +0 -3
- data/test/iruby/session_test.rb +1 -0
- data/test/iruby/utils_test.rb +25 -0
- data/test/run-test.rb +1 -0
- metadata +22 -12
- data/CHANGES +0 -167
data/lib/iruby/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -1,10 +1,56 @@
|
|
1
1
|
require "iruby"
|
2
|
+
require "json"
|
3
|
+
require 'multi_json'
|
4
|
+
require "pathname"
|
2
5
|
require "test/unit"
|
3
6
|
require "test/unit/rr"
|
4
7
|
require "tmpdir"
|
5
8
|
|
9
|
+
|
10
|
+
IRuby.logger = IRuby::MultiLogger.new(*Logger.new(STDERR, level: Logger::Severity::INFO))
|
11
|
+
|
6
12
|
module IRubyTest
|
7
13
|
class TestBase < Test::Unit::TestCase
|
14
|
+
def self.startup
|
15
|
+
@__config_dir = Dir.mktmpdir("iruby-test")
|
16
|
+
@__config_path = Pathname.new(@__config_dir) + "config.json"
|
17
|
+
File.write(@__config_path, {
|
18
|
+
control_port: 50160,
|
19
|
+
shell_port: 57503,
|
20
|
+
transport: "tcp",
|
21
|
+
signature_scheme: "hmac-sha256",
|
22
|
+
stdin_port: 52597,
|
23
|
+
hb_port: 42540,
|
24
|
+
ip: "127.0.0.1",
|
25
|
+
iopub_port: 40885,
|
26
|
+
key: "a0436f6c-1916-498b-8eb9-e81ab9368e84"
|
27
|
+
}.to_json)
|
28
|
+
|
29
|
+
@__original_kernel_instance = IRuby::Kernel.instance
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.shutdown
|
33
|
+
FileUtils.remove_entry_secure(@__config_dir)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.test_config_filename
|
37
|
+
@__config_path.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.restore_kernel
|
41
|
+
IRuby::Kernel.instance = @__original_kernel_instance
|
42
|
+
end
|
43
|
+
|
44
|
+
def teardown
|
45
|
+
self.class.restore_kernel
|
46
|
+
end
|
47
|
+
|
48
|
+
def with_session_adapter(session_adapter_name)
|
49
|
+
IRuby::Kernel.new(self.class.test_config_filename, session_adapter_name)
|
50
|
+
$stdout = STDOUT
|
51
|
+
$stderr = STDERR
|
52
|
+
end
|
53
|
+
|
8
54
|
def assert_output(stdout=nil, stderr=nil)
|
9
55
|
flunk "assert_output requires a block to capture output." unless block_given?
|
10
56
|
|
data/test/iruby/backend_test.rb
CHANGED
@@ -8,6 +8,12 @@ module IRubyTest
|
|
8
8
|
assert_equal 3, @plainbackend.eval('1+2', false)
|
9
9
|
end
|
10
10
|
|
11
|
+
def test_include_module
|
12
|
+
assert_nothing_raised do
|
13
|
+
@plainbackend.eval("include Math, Comparable", false)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
11
17
|
def test_complete_req
|
12
18
|
assert_includes @plainbackend.complete('req'), 'require'
|
13
19
|
end
|
@@ -26,6 +32,12 @@ module IRubyTest
|
|
26
32
|
assert_equal 3, @prybackend.eval('1+2', false)
|
27
33
|
end
|
28
34
|
|
35
|
+
def test_include_module
|
36
|
+
assert_nothing_raised do
|
37
|
+
@prybackend.eval("include Math, Comparable", false)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
29
41
|
def test_complete_req
|
30
42
|
assert_includes @prybackend.complete('req'), 'require'
|
31
43
|
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module IRubyTest
|
2
|
+
class DisplayTest < TestBase
|
3
|
+
def setup
|
4
|
+
@object = Object.new
|
5
|
+
@object.instance_variable_set(:@to_html_called, false)
|
6
|
+
@object.instance_variable_set(:@to_markdown_called, false)
|
7
|
+
@object.instance_variable_set(:@to_iruby_called, false)
|
8
|
+
@object.instance_variable_set(:@to_iruby_mimebundle_called, false)
|
9
|
+
|
10
|
+
class << @object
|
11
|
+
attr_reader :to_html_called
|
12
|
+
attr_reader :to_markdown_called
|
13
|
+
attr_reader :to_iruby_called
|
14
|
+
attr_reader :to_iruby_mimebundle_called
|
15
|
+
|
16
|
+
def html
|
17
|
+
"<b>html</b>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def markdown
|
21
|
+
"*markdown*"
|
22
|
+
end
|
23
|
+
|
24
|
+
def inspect
|
25
|
+
"!!! inspect !!!"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def define_to_html
|
31
|
+
class << @object
|
32
|
+
def to_html
|
33
|
+
@to_html_called = true
|
34
|
+
html
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def define_to_markdown
|
40
|
+
class << @object
|
41
|
+
def to_markdown
|
42
|
+
@to_markdown_called = true
|
43
|
+
markdown
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def define_to_iruby
|
49
|
+
class << @object
|
50
|
+
def to_iruby
|
51
|
+
@to_iruby_called = true
|
52
|
+
["text/html", "<b>to_iruby</b>"]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def define_to_iruby_mimebundle
|
58
|
+
class << @object
|
59
|
+
def to_iruby_mimebundle(include: [])
|
60
|
+
@to_iruby_mimebundle_called = true
|
61
|
+
mimes = if include.empty?
|
62
|
+
["text/html", "text/markdown", "application/json"]
|
63
|
+
else
|
64
|
+
include
|
65
|
+
end
|
66
|
+
formats = mimes.map { |mime|
|
67
|
+
result = case mime
|
68
|
+
when "text/html"
|
69
|
+
"<i>html</i>"
|
70
|
+
when "text/markdown"
|
71
|
+
"**markdown**"
|
72
|
+
when "application/json"
|
73
|
+
%Q[{"mimebundle": "json"}]
|
74
|
+
end
|
75
|
+
[mime, result]
|
76
|
+
}.to_h
|
77
|
+
metadata = {}
|
78
|
+
return formats, metadata
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def assert_iruby_display(expected)
|
84
|
+
assert_equal(expected,
|
85
|
+
{
|
86
|
+
result: IRuby::Display.display(@object),
|
87
|
+
to_html_called: @object.to_html_called,
|
88
|
+
to_markdown_called: @object.to_markdown_called,
|
89
|
+
to_iruby_called: @object.to_iruby_called,
|
90
|
+
to_iruby_mimebundle_called: @object.to_iruby_mimebundle_called
|
91
|
+
})
|
92
|
+
end
|
93
|
+
|
94
|
+
sub_test_case("the object cannot handle all the mime types") do
|
95
|
+
def test_display
|
96
|
+
assert_iruby_display({
|
97
|
+
result: {"text/plain" => "!!! inspect !!!"},
|
98
|
+
to_html_called: false,
|
99
|
+
to_markdown_called: false,
|
100
|
+
to_iruby_called: false,
|
101
|
+
to_iruby_mimebundle_called: false
|
102
|
+
})
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
sub_test_case("the object can respond to to_iruby") do
|
107
|
+
def setup
|
108
|
+
super
|
109
|
+
define_to_iruby
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_display
|
113
|
+
assert_iruby_display({
|
114
|
+
result: {
|
115
|
+
"text/html" => "<b>to_iruby</b>",
|
116
|
+
"text/plain" => "!!! inspect !!!"
|
117
|
+
},
|
118
|
+
to_html_called: false,
|
119
|
+
to_markdown_called: false,
|
120
|
+
to_iruby_called: true,
|
121
|
+
to_iruby_mimebundle_called: false
|
122
|
+
})
|
123
|
+
end
|
124
|
+
|
125
|
+
sub_test_case("the object can respond to to_markdown") do
|
126
|
+
def setup
|
127
|
+
super
|
128
|
+
define_to_markdown
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_display
|
132
|
+
assert_iruby_display({
|
133
|
+
result: {
|
134
|
+
"text/markdown" => "*markdown*",
|
135
|
+
"text/plain" => "!!! inspect !!!"
|
136
|
+
},
|
137
|
+
to_html_called: false,
|
138
|
+
to_markdown_called: true,
|
139
|
+
to_iruby_called: false,
|
140
|
+
to_iruby_mimebundle_called: false
|
141
|
+
})
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
sub_test_case("the object can respond to to_html") do
|
146
|
+
def setup
|
147
|
+
super
|
148
|
+
define_to_html
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_display
|
152
|
+
assert_iruby_display({
|
153
|
+
result: {
|
154
|
+
"text/html" => "<b>html</b>",
|
155
|
+
"text/plain" => "!!! inspect !!!"
|
156
|
+
},
|
157
|
+
to_html_called: true,
|
158
|
+
to_markdown_called: false,
|
159
|
+
to_iruby_called: false,
|
160
|
+
to_iruby_mimebundle_called: false
|
161
|
+
})
|
162
|
+
end
|
163
|
+
|
164
|
+
sub_test_case("the object can respond to to_iruby_mimebundle") do
|
165
|
+
def setup
|
166
|
+
super
|
167
|
+
define_to_iruby_mimebundle
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_display
|
171
|
+
assert_iruby_display({
|
172
|
+
result: {
|
173
|
+
"text/html" => "<i>html</i>",
|
174
|
+
"text/markdown" => "**markdown**",
|
175
|
+
"application/json" => %Q[{"mimebundle": "json"}],
|
176
|
+
"text/plain" => "!!! inspect !!!"
|
177
|
+
},
|
178
|
+
to_html_called: false,
|
179
|
+
to_markdown_called: false,
|
180
|
+
to_iruby_called: false,
|
181
|
+
to_iruby_mimebundle_called: true
|
182
|
+
})
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module IRubyTest
|
2
|
+
class EventManagerTest < TestBase
|
3
|
+
def setup
|
4
|
+
@man = IRuby::EventManager.new([:foo, :bar])
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_available_events
|
8
|
+
assert_equal([:foo, :bar],
|
9
|
+
@man.available_events)
|
10
|
+
end
|
11
|
+
|
12
|
+
sub_test_case("#register") do
|
13
|
+
sub_test_case("known event name") do
|
14
|
+
def test_register
|
15
|
+
fn = ->() {}
|
16
|
+
assert_equal(fn,
|
17
|
+
@man.register(:foo, &fn))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
sub_test_case("unknown event name") do
|
22
|
+
def test_register
|
23
|
+
assert_raise_message("Unknown event name: baz") do
|
24
|
+
@man.register(:baz) {}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
sub_test_case("#unregister") do
|
31
|
+
sub_test_case("no event is registered") do
|
32
|
+
def test_unregister
|
33
|
+
fn = ->() {}
|
34
|
+
assert_raise_message("Given callable object #{fn} is not registered as a foo callback") do
|
35
|
+
@man.unregister(:foo, fn)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
sub_test_case("the registered callable is given") do
|
41
|
+
def test_unregister
|
42
|
+
results = { values: [] }
|
43
|
+
fn = ->(a) { values << a }
|
44
|
+
|
45
|
+
@man.register(:foo, &fn)
|
46
|
+
|
47
|
+
results[:retval] = @man.unregister(:foo, fn)
|
48
|
+
|
49
|
+
@man.trigger(:foo, 42)
|
50
|
+
|
51
|
+
assert_equal({
|
52
|
+
values: [],
|
53
|
+
retval: fn
|
54
|
+
},
|
55
|
+
results)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
sub_test_case("#trigger") do
|
61
|
+
sub_test_case("no event is registered") do
|
62
|
+
def test_trigger
|
63
|
+
assert_nothing_raised do
|
64
|
+
@man.trigger(:foo)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
sub_test_case("some events are registered") do
|
70
|
+
def test_trigger
|
71
|
+
values = []
|
72
|
+
@man.register(:foo) {|a| values << a }
|
73
|
+
@man.register(:foo) {|a| values << 10*a }
|
74
|
+
@man.register(:foo) {|a| values << 100+a }
|
75
|
+
|
76
|
+
@man.trigger(:foo, 5)
|
77
|
+
|
78
|
+
assert_equal([5, 50, 105],
|
79
|
+
values)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
sub_test_case("unknown event name") do
|
84
|
+
def test_trigger
|
85
|
+
assert_raise_message("Unknown event name: baz") do
|
86
|
+
@man.trigger(:baz, 100)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require "base64"
|
2
|
+
|
3
|
+
module IRubyTest
|
4
|
+
class KernelTest < TestBase
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
with_session_adapter("test")
|
8
|
+
@kernel = IRuby::Kernel.instance
|
9
|
+
end
|
10
|
+
|
11
|
+
sub_test_case("iruby_initialized event") do
|
12
|
+
def setup
|
13
|
+
super
|
14
|
+
@initialized_kernel = nil
|
15
|
+
@callback = IRuby::Kernel.events.register(:initialized) do |kernel|
|
16
|
+
@initialized_kernel = kernel
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def teardown
|
21
|
+
IRuby::Kernel.events.unregister(:initialized, @callback)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_iruby_initialized_event
|
25
|
+
with_session_adapter("test")
|
26
|
+
assert_same(IRuby::Kernel.instance, @initialized_kernel)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_execute_request
|
31
|
+
obj = Object.new
|
32
|
+
|
33
|
+
class << obj
|
34
|
+
def to_html
|
35
|
+
"<b>HTML</b>"
|
36
|
+
end
|
37
|
+
|
38
|
+
def inspect
|
39
|
+
"!!! inspect !!!"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
::IRubyTest.define_singleton_method(:test_object) { obj }
|
44
|
+
|
45
|
+
msg_types = []
|
46
|
+
execute_reply = nil
|
47
|
+
execute_result = nil
|
48
|
+
@kernel.session.adapter.send_callback = ->(sock, msg) do
|
49
|
+
header = msg[:header]
|
50
|
+
content = msg[:content]
|
51
|
+
msg_types << header["msg_type"]
|
52
|
+
case header["msg_type"]
|
53
|
+
when "execute_reply"
|
54
|
+
execute_reply = content
|
55
|
+
when "execute_result"
|
56
|
+
execute_result = content
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
msg = {
|
61
|
+
content: {
|
62
|
+
"code" => "IRubyTest.test_object",
|
63
|
+
"silent" => false,
|
64
|
+
"store_history" => false,
|
65
|
+
"user_expressions" => {},
|
66
|
+
"allow_stdin" => false,
|
67
|
+
"stop_on_error" => true,
|
68
|
+
}
|
69
|
+
}
|
70
|
+
@kernel.execute_request(msg)
|
71
|
+
|
72
|
+
assert_equal({
|
73
|
+
msg_types: [ "execute_input", "execute_result", "execute_reply" ],
|
74
|
+
execute_reply: {
|
75
|
+
status: "ok",
|
76
|
+
user_expressions: {},
|
77
|
+
},
|
78
|
+
execute_result: {
|
79
|
+
data: {
|
80
|
+
"text/html" => "<b>HTML</b>",
|
81
|
+
"text/plain" => "!!! inspect !!!"
|
82
|
+
},
|
83
|
+
metadata: {},
|
84
|
+
}
|
85
|
+
},
|
86
|
+
{
|
87
|
+
msg_types: msg_types,
|
88
|
+
execute_reply: {
|
89
|
+
status: execute_reply["status"],
|
90
|
+
user_expressions: execute_reply["user_expressions"]
|
91
|
+
},
|
92
|
+
execute_result: {
|
93
|
+
data: execute_result["data"],
|
94
|
+
metadata: execute_result["metadata"]
|
95
|
+
}
|
96
|
+
})
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_events_around_of_execute_request
|
100
|
+
event_history = []
|
101
|
+
|
102
|
+
@kernel.events.register(:pre_execute) do
|
103
|
+
event_history << :pre_execute
|
104
|
+
end
|
105
|
+
|
106
|
+
@kernel.events.register(:pre_run_cell) do |exec_info|
|
107
|
+
event_history << [:pre_run_cell, exec_info]
|
108
|
+
end
|
109
|
+
|
110
|
+
@kernel.events.register(:post_execute) do
|
111
|
+
event_history << :post_execute
|
112
|
+
end
|
113
|
+
|
114
|
+
@kernel.events.register(:post_run_cell) do |result|
|
115
|
+
event_history << [:post_run_cell, result]
|
116
|
+
end
|
117
|
+
|
118
|
+
msg = {
|
119
|
+
content: {
|
120
|
+
"code" => "true",
|
121
|
+
"silent" => false,
|
122
|
+
"store_history" => false,
|
123
|
+
"user_expressions" => {},
|
124
|
+
"allow_stdin" => false,
|
125
|
+
"stop_on_error" => true,
|
126
|
+
}
|
127
|
+
}
|
128
|
+
@kernel.execute_request(msg)
|
129
|
+
|
130
|
+
msg = {
|
131
|
+
content: {
|
132
|
+
"code" => "true",
|
133
|
+
"silent" => true,
|
134
|
+
"store_history" => false,
|
135
|
+
"user_expressions" => {},
|
136
|
+
"allow_stdin" => false,
|
137
|
+
"stop_on_error" => true,
|
138
|
+
}
|
139
|
+
}
|
140
|
+
@kernel.execute_request(msg)
|
141
|
+
|
142
|
+
assert_equal([
|
143
|
+
:pre_execute,
|
144
|
+
[:pre_run_cell, IRuby::ExecutionInfo.new("true", false, false)],
|
145
|
+
:post_execute,
|
146
|
+
[:post_run_cell, true],
|
147
|
+
:pre_execute,
|
148
|
+
:post_execute
|
149
|
+
],
|
150
|
+
event_history)
|
151
|
+
end
|
152
|
+
|
153
|
+
sub_test_case("#switch_backend!") do
|
154
|
+
sub_test_case("") do
|
155
|
+
def test_switch_backend
|
156
|
+
classes = []
|
157
|
+
|
158
|
+
# First pick the default backend class
|
159
|
+
classes << @kernel.instance_variable_get(:@backend).class
|
160
|
+
|
161
|
+
@kernel.switch_backend!(:pry)
|
162
|
+
classes << @kernel.instance_variable_get(:@backend).class
|
163
|
+
|
164
|
+
@kernel.switch_backend!(:irb)
|
165
|
+
classes << @kernel.instance_variable_get(:@backend).class
|
166
|
+
|
167
|
+
@kernel.switch_backend!(:pry)
|
168
|
+
classes << @kernel.instance_variable_get(:@backend).class
|
169
|
+
|
170
|
+
@kernel.switch_backend!(:plain)
|
171
|
+
classes << @kernel.instance_variable_get(:@backend).class
|
172
|
+
|
173
|
+
assert_equal([
|
174
|
+
IRuby::PlainBackend,
|
175
|
+
IRuby::PryBackend,
|
176
|
+
IRuby::PlainBackend,
|
177
|
+
IRuby::PryBackend,
|
178
|
+
IRuby::PlainBackend
|
179
|
+
],
|
180
|
+
classes)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|