iruby 0.4.0 → 0.7.1
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 +69 -0
- data/CHANGES.md +219 -0
- data/Gemfile +0 -2
- data/LICENSE +1 -1
- data/README.md +81 -62
- data/Rakefile +10 -10
- data/ci/Dockerfile.main.erb +1 -3
- data/iruby.gemspec +13 -19
- data/lib/iruby.rb +6 -6
- data/lib/iruby/backend.rb +38 -10
- data/lib/iruby/command.rb +2 -6
- data/lib/iruby/display.rb +216 -81
- data/lib/iruby/event_manager.rb +40 -0
- data/lib/iruby/formatter.rb +3 -3
- data/lib/iruby/input.rb +6 -6
- data/lib/iruby/input/autoload.rb +1 -1
- data/lib/iruby/input/builder.rb +4 -4
- data/lib/iruby/input/button.rb +2 -2
- data/lib/iruby/input/cancel.rb +1 -1
- data/lib/iruby/input/checkbox.rb +3 -3
- data/lib/iruby/input/date.rb +3 -3
- data/lib/iruby/input/field.rb +2 -2
- data/lib/iruby/input/file.rb +3 -3
- data/lib/iruby/input/form.rb +6 -6
- data/lib/iruby/input/label.rb +4 -4
- data/lib/iruby/input/multiple.rb +10 -10
- data/lib/iruby/input/popup.rb +2 -2
- data/lib/iruby/input/radio.rb +6 -6
- data/lib/iruby/input/select.rb +8 -8
- data/lib/iruby/input/textarea.rb +1 -1
- data/lib/iruby/input/widget.rb +2 -2
- data/lib/iruby/jupyter.rb +1 -0
- data/lib/iruby/kernel.rb +157 -29
- data/lib/iruby/ostream.rb +27 -10
- data/lib/iruby/session.rb +1 -0
- data/lib/iruby/session_adapter.rb +7 -3
- data/lib/iruby/session_adapter/pyzmq_adapter.rb +11 -10
- data/lib/iruby/session_adapter/test_adapter.rb +49 -0
- data/lib/iruby/utils.rb +15 -0
- data/lib/iruby/version.rb +1 -1
- data/run-test.sh +1 -1
- data/test/helper.rb +136 -0
- data/test/integration_test.rb +1 -2
- data/test/iruby/backend_test.rb +37 -0
- data/test/iruby/command_test.rb +0 -1
- data/test/iruby/display_test.rb +188 -0
- data/test/iruby/event_manager_test.rb +92 -0
- data/test/iruby/jupyter_test.rb +0 -1
- data/test/iruby/kernel_test.rb +185 -0
- data/test/iruby/mime_test.rb +50 -0
- data/test/iruby/multi_logger_test.rb +0 -4
- data/test/iruby/session_adapter/cztop_adapter_test.rb +1 -1
- data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +1 -1
- data/test/iruby/session_adapter/session_adapter_test_base.rb +1 -3
- data/test/iruby/session_adapter_test.rb +42 -67
- data/test/iruby/session_test.rb +10 -15
- data/test/run-test.rb +19 -0
- metadata +74 -62
- data/.travis.yml +0 -41
- data/CHANGES +0 -143
- data/CONTRIBUTORS +0 -19
- data/lib/iruby/session/rbczmq.rb +0 -72
- data/lib/iruby/session_adapter/rbczmq_adapter.rb +0 -33
- data/test/iruby/session_adapter/rbczmq_adapter_test.rb +0 -37
- data/test/test_helper.rb +0 -48
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'iruby/session/mixin'
|
2
|
+
|
3
|
+
module IRuby
|
4
|
+
module SessionAdapter
|
5
|
+
class TestAdapter < BaseAdapter
|
6
|
+
include IRuby::SessionSerialize
|
7
|
+
|
8
|
+
DummySocket = Struct.new(:type, :protocol, :host, :port)
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
super
|
12
|
+
|
13
|
+
unless config['key'].empty? || config['signature_scheme'].empty?
|
14
|
+
unless config['signature_scheme'] =~ /\Ahmac-/
|
15
|
+
raise "Unknown signature_scheme: #{config['signature_scheme']}"
|
16
|
+
end
|
17
|
+
digest_algorithm = config['signature_scheme'][/\Ahmac-(.*)\Z/, 1]
|
18
|
+
@hmac = OpenSSL::HMAC.new(config['key'], OpenSSL::Digest.new(digest_algorithm))
|
19
|
+
end
|
20
|
+
|
21
|
+
@send_callback = nil
|
22
|
+
@recv_callback = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_accessor :send_callback, :recv_callback
|
26
|
+
|
27
|
+
def send(sock, data)
|
28
|
+
unless @send_callback.nil?
|
29
|
+
@send_callback.call(sock, unserialize(data))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def recv(sock)
|
34
|
+
unless @recv_callback.nil?
|
35
|
+
serialize(@recv_callback.call(sock))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def heartbeat_loop(sock)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def make_socket(type, protocol, host, port)
|
45
|
+
DummySocket.new(type, protocol, host, port)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/iruby/utils.rb
CHANGED
@@ -4,33 +4,48 @@ module IRuby
|
|
4
4
|
Display.convert(object, options)
|
5
5
|
end
|
6
6
|
|
7
|
+
# Display the object
|
7
8
|
def display(obj, options = {})
|
8
9
|
Kernel.instance.session.send(:publish, :display_data,
|
9
10
|
data: Display.display(obj, options),
|
10
11
|
metadata: {}) unless obj.nil?
|
12
|
+
# The next `nil` is necessary to prevent unintentional displaying
|
13
|
+
# the result of Session#send
|
14
|
+
nil
|
11
15
|
end
|
12
16
|
|
17
|
+
# Clear the output area
|
18
|
+
def clear_output(wait=false)
|
19
|
+
Display.clear_output(wait)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Format the given object into HTML table
|
13
23
|
def table(s, **options)
|
14
24
|
html(HTML.table(s, options))
|
15
25
|
end
|
16
26
|
|
27
|
+
# Treat the given string as LaTeX text
|
17
28
|
def latex(s)
|
18
29
|
convert(s, mime: 'text/latex')
|
19
30
|
end
|
20
31
|
alias tex latex
|
21
32
|
|
33
|
+
# Format the given string of TeX equation into LaTeX text
|
22
34
|
def math(s)
|
23
35
|
convert("$$#{s}$$", mime: 'text/latex')
|
24
36
|
end
|
25
37
|
|
38
|
+
# Treat the given string as HTML
|
26
39
|
def html(s)
|
27
40
|
convert(s, mime: 'text/html')
|
28
41
|
end
|
29
42
|
|
43
|
+
# Treat the given string as JavaScript code
|
30
44
|
def javascript(s)
|
31
45
|
convert(s, mime: 'application/javascript')
|
32
46
|
end
|
33
47
|
|
48
|
+
# Treat the given string as SVG text
|
34
49
|
def svg(s)
|
35
50
|
convert(s, mime: 'image/svg+xml')
|
36
51
|
end
|
data/lib/iruby/version.rb
CHANGED
data/run-test.sh
CHANGED
data/test/helper.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
require "iruby"
|
2
|
+
require "json"
|
3
|
+
require 'multi_json'
|
4
|
+
require "pathname"
|
5
|
+
require "test/unit"
|
6
|
+
require "test/unit/rr"
|
7
|
+
require "tmpdir"
|
8
|
+
|
9
|
+
|
10
|
+
IRuby.logger = IRuby::MultiLogger.new(*Logger.new(STDERR, level: Logger::Severity::INFO))
|
11
|
+
|
12
|
+
module IRubyTest
|
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
|
+
|
54
|
+
def assert_output(stdout=nil, stderr=nil)
|
55
|
+
flunk "assert_output requires a block to capture output." unless block_given?
|
56
|
+
|
57
|
+
out, err = capture_io do
|
58
|
+
yield
|
59
|
+
end
|
60
|
+
|
61
|
+
y = check_assert_output_result(stderr, err, "stderr")
|
62
|
+
x = check_assert_output_result(stdout, out, "stdout")
|
63
|
+
|
64
|
+
(!stdout || x) && (!stderr || y)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def capture_io
|
70
|
+
captured_stdout = StringIO.new
|
71
|
+
captured_stderr = StringIO.new
|
72
|
+
|
73
|
+
orig_stdout, $stdout = $stdout, captured_stdout
|
74
|
+
orig_stderr, $stderr = $stderr, captured_stderr
|
75
|
+
|
76
|
+
yield
|
77
|
+
|
78
|
+
return captured_stdout.string, captured_stderr.string
|
79
|
+
ensure
|
80
|
+
$stdout = orig_stdout
|
81
|
+
$stderr = orig_stderr
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_assert_output_result(expected, actual, name)
|
85
|
+
if expected
|
86
|
+
message = "In #{name}"
|
87
|
+
case expected
|
88
|
+
when Regexp
|
89
|
+
assert_match(expected, actual, message)
|
90
|
+
else
|
91
|
+
assert_equal(expected, actual, message)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def ignore_warning
|
97
|
+
saved, $VERBOSE = $VERBOSE , nil
|
98
|
+
yield
|
99
|
+
ensure
|
100
|
+
$VERBOSE = saved
|
101
|
+
end
|
102
|
+
|
103
|
+
def with_env(env)
|
104
|
+
keys = env.keys
|
105
|
+
saved_values = ENV.values_at(*keys)
|
106
|
+
ENV.update(env)
|
107
|
+
yield
|
108
|
+
ensure
|
109
|
+
if keys && saved_values
|
110
|
+
keys.zip(saved_values) do |k, v|
|
111
|
+
ENV[k] = v
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def windows_only
|
117
|
+
omit('windows only test') unless windows?
|
118
|
+
end
|
119
|
+
|
120
|
+
def apple_only
|
121
|
+
omit('apple only test') unless windows?
|
122
|
+
end
|
123
|
+
|
124
|
+
def unix_only
|
125
|
+
omit('unix only test') if windows? || apple?
|
126
|
+
end
|
127
|
+
|
128
|
+
def windows?
|
129
|
+
/mingw|mswin/ =~ RUBY_PLATFORM
|
130
|
+
end
|
131
|
+
|
132
|
+
def apple?
|
133
|
+
/darwin/ =~ RUBY_PLATFORM
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
data/test/integration_test.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'test_helper'
|
2
1
|
require 'pty'
|
3
2
|
require 'expect'
|
4
3
|
|
@@ -33,7 +32,7 @@ class IRubyTest::IntegrationTest < IRubyTest::TestBase
|
|
33
32
|
end
|
34
33
|
|
35
34
|
def test_interaction
|
36
|
-
|
35
|
+
omit("This test too much unstable")
|
37
36
|
|
38
37
|
write '"Hello, world!"'
|
39
38
|
expect '"Hello, world!"'
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module IRubyTest
|
2
|
+
class PlainBackendTest < IRubyTest::TestBase
|
3
|
+
def setup
|
4
|
+
@plainbackend = IRuby::PlainBackend.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def test_eval_one_plus_two
|
8
|
+
assert_equal 3, @plainbackend.eval('1+2', false)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_complete_req
|
12
|
+
assert_includes @plainbackend.complete('req'), 'require'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_complete_2_dot
|
16
|
+
assert_includes @plainbackend.complete('2.'), '2.even?'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class PryBackendTest < IRubyTest::TestBase
|
21
|
+
def setup
|
22
|
+
@prybackend = IRuby::PryBackend.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_eval_one_plus_two
|
26
|
+
assert_equal 3, @prybackend.eval('1+2', false)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_complete_req
|
30
|
+
assert_includes @prybackend.complete('req'), 'require'
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_complete_2_dot
|
34
|
+
assert_includes @prybackend.complete('2.'), '2.even?'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/test/iruby/command_test.rb
CHANGED
@@ -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
|