iruby 0.3 → 0.4.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.
- checksums.yaml +5 -5
- data/.travis.yml +35 -10
- data/Gemfile +4 -0
- data/README.md +115 -84
- data/Rakefile +26 -0
- data/ci/Dockerfile.base.erb +41 -0
- data/ci/Dockerfile.main.erb +9 -0
- data/ci/requirements.txt +1 -0
- data/docker/setup.sh +15 -0
- data/docker/test.sh +7 -0
- data/iruby.gemspec +4 -2
- data/lib/iruby.rb +13 -7
- data/lib/iruby/command.rb +67 -11
- data/lib/iruby/input/README.md +299 -0
- data/lib/iruby/jupyter.rb +76 -0
- data/lib/iruby/kernel.rb +49 -9
- data/lib/iruby/ostream.rb +4 -0
- data/lib/iruby/session.rb +116 -0
- data/lib/iruby/session/cztop.rb +4 -0
- data/lib/iruby/session/rbczmq.rb +5 -1
- data/lib/iruby/session_adapter.rb +68 -0
- data/lib/iruby/session_adapter/cztop_adapter.rb +45 -0
- data/lib/iruby/session_adapter/ffirzmq_adapter.rb +55 -0
- data/lib/iruby/session_adapter/pyzmq_adapter.rb +76 -0
- data/lib/iruby/session_adapter/rbczmq_adapter.rb +33 -0
- data/lib/iruby/utils.rb +1 -2
- data/lib/iruby/version.rb +1 -1
- data/run-test.sh +12 -0
- data/tasks/ci.rake +65 -0
- data/test/integration_test.rb +22 -10
- data/test/iruby/command_test.rb +208 -0
- data/test/iruby/jupyter_test.rb +28 -0
- data/test/iruby/multi_logger_test.rb +1 -1
- data/test/iruby/session_adapter/cztop_adapter_test.rb +20 -0
- data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +20 -0
- data/test/iruby/session_adapter/rbczmq_adapter_test.rb +37 -0
- data/test/iruby/session_adapter/session_adapter_test_base.rb +29 -0
- data/test/iruby/session_adapter_test.rb +116 -0
- data/test/iruby/session_test.rb +53 -0
- data/test/test_helper.rb +44 -1
- metadata +72 -12
@@ -0,0 +1,55 @@
|
|
1
|
+
module IRuby
|
2
|
+
module SessionAdapter
|
3
|
+
class FfirzmqAdapter < BaseAdapter
|
4
|
+
def self.load_requirements
|
5
|
+
require 'ffi-rzmq'
|
6
|
+
end
|
7
|
+
|
8
|
+
def send(sock, data)
|
9
|
+
data.each_with_index do |part, i|
|
10
|
+
sock.send_string(part, i == data.size - 1 ? 0 : ZMQ::SNDMORE)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def recv(sock)
|
15
|
+
msg = []
|
16
|
+
while msg.empty? || sock.more_parts?
|
17
|
+
begin
|
18
|
+
frame = ''
|
19
|
+
rc = sock.recv_string(frame)
|
20
|
+
ZMQ::Util.error_check('zmq_msg_recv', rc)
|
21
|
+
msg << frame
|
22
|
+
rescue
|
23
|
+
end
|
24
|
+
end
|
25
|
+
msg
|
26
|
+
end
|
27
|
+
|
28
|
+
def heartbeat_loop(sock)
|
29
|
+
@heartbeat_device = ZMQ::Device.new(sock, sock)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def make_socket(type, protocol, host, port)
|
35
|
+
case type
|
36
|
+
when :ROUTER, :PUB, :REP
|
37
|
+
type = ZMQ.const_get(type)
|
38
|
+
else
|
39
|
+
if ZMQ.const_defined?(type)
|
40
|
+
raise ArgumentError, "Unsupported ZMQ socket type: #{type_symbol}"
|
41
|
+
else
|
42
|
+
raise ArgumentError, "Invalid ZMQ socket type: #{type_symbol}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
zmq_context.socket(type).tap do |sock|
|
46
|
+
sock.bind("#{protocol}://#{host}:#{port}")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def zmq_context
|
51
|
+
@zmq_context ||= ZMQ::Context.new
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module IRuby
|
2
|
+
module SessionAdapter
|
3
|
+
class PyzmqAdapter < BaseAdapter
|
4
|
+
def self.load_requirements
|
5
|
+
require 'pycall'
|
6
|
+
@zmq = PyCall.import_module('zmq')
|
7
|
+
rescue PyCall::PyError => error
|
8
|
+
raise LoadError, error.message
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_reader :zmq
|
13
|
+
end
|
14
|
+
|
15
|
+
def make_router_socket(protocol, host, port)
|
16
|
+
make_socket(:ROUTER, protocol, host, port)
|
17
|
+
end
|
18
|
+
|
19
|
+
def make_pub_socket(protocol, host, port)
|
20
|
+
make_socket(:PUB, protocol, host, port)
|
21
|
+
end
|
22
|
+
|
23
|
+
def make_pub_socket(protocol, host, port)
|
24
|
+
make_socket(:REP, protocol, host, port)
|
25
|
+
end
|
26
|
+
|
27
|
+
def heartbeat_loop(sock)
|
28
|
+
PyCall.sys.path.append(File.expand_path('../pyzmq', __FILE__))
|
29
|
+
heartbeat = PyCall.import_module('iruby.heartbeat')
|
30
|
+
@heartbeat_thread = heartbeat.Heartbeat.new(sock)
|
31
|
+
@heartbeat_thread.start
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def socket_type(type_symbol)
|
37
|
+
case type_symbol
|
38
|
+
when :ROUTER, :PUB, :REP
|
39
|
+
zmq[type_symbol]
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Unknown ZMQ socket type: #{type_symbol}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def make_socket(type_symbol, protocol, host, port)
|
46
|
+
type = socket_type(type_symbol)
|
47
|
+
sock = zmq_context.socket(type)
|
48
|
+
bind_socket(sock, protocol, host, port)
|
49
|
+
sock
|
50
|
+
end
|
51
|
+
|
52
|
+
def bind_socket(sock, protocol, host, port)
|
53
|
+
iface = "#{protocol}://#{host}"
|
54
|
+
case protocol
|
55
|
+
when 'tcp'
|
56
|
+
if port <= 0
|
57
|
+
port = sock.bind_to_random_port(iface)
|
58
|
+
else
|
59
|
+
sock.bind("#{iface}:#{port}")
|
60
|
+
end
|
61
|
+
else
|
62
|
+
raise ArgumentError, "Unsupported protocol: #{protocol}"
|
63
|
+
end
|
64
|
+
[sock, port]
|
65
|
+
end
|
66
|
+
|
67
|
+
def zmq_context
|
68
|
+
zmq.Context.instance
|
69
|
+
end
|
70
|
+
|
71
|
+
def zmq
|
72
|
+
self.class.zmq
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module IRuby
|
2
|
+
module SessionAdapter
|
3
|
+
class RbczmqAdapter < BaseAdapter
|
4
|
+
def self.load_requirements
|
5
|
+
require 'rbczmq'
|
6
|
+
end
|
7
|
+
|
8
|
+
def send(sock, data)
|
9
|
+
sock.send_message(ZMQ::Message(*data))
|
10
|
+
end
|
11
|
+
|
12
|
+
def recv(sock)
|
13
|
+
sock.recv_message
|
14
|
+
end
|
15
|
+
|
16
|
+
def heartbeat_loop(sock)
|
17
|
+
ZMQ.proxy(sock, sock)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def make_socket(type, protocol, host, port)
|
23
|
+
zmq_context.socket(type).tap do |sock|
|
24
|
+
sock.bind("#{protocol}://#{host}:#{port}")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def zmq_context
|
29
|
+
@zmq_context ||= ZMQ::Context.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/iruby/utils.rb
CHANGED
data/lib/iruby/version.rb
CHANGED
data/run-test.sh
ADDED
data/tasks/ci.rake
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
namespace :ci do
|
2
|
+
namespace :docker do
|
3
|
+
def ruby_version
|
4
|
+
@ruby_version ||= ENV['ruby_version']
|
5
|
+
end
|
6
|
+
|
7
|
+
def ruby_image_name
|
8
|
+
@ruby_image_name ||= "rubylang/ruby:#{ruby_version}-bionic"
|
9
|
+
end
|
10
|
+
|
11
|
+
def iruby_test_base_image_name
|
12
|
+
@iruby_test_base_image_name ||= "iruby-test-base:ruby-#{ruby_version}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def iruby_test_image_name
|
16
|
+
@docker_image_name ||= begin
|
17
|
+
"sciruby/iruby-test:ruby-#{ruby_version}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def docker_image_found?(image_name)
|
22
|
+
image_id = `docker images -q #{image_name}`.chomp
|
23
|
+
image_id.length > 0
|
24
|
+
end
|
25
|
+
|
26
|
+
directory 'tmp'
|
27
|
+
|
28
|
+
desc "Build iruby-test-base docker image"
|
29
|
+
task :build_test_base_image => 'tmp' do
|
30
|
+
unless docker_image_found?(iruby_test_base_image_name)
|
31
|
+
require 'erb'
|
32
|
+
dockerfile_content = ERB.new(File.read('ci/Dockerfile.base.erb')).result(binding)
|
33
|
+
File.write('tmp/Dockerfile', dockerfile_content)
|
34
|
+
sh 'docker', 'build', '-t', iruby_test_base_image_name, '-f', 'tmp/Dockerfile', '.'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Pull docker image of ruby"
|
39
|
+
task :pull_ruby_image do
|
40
|
+
sh 'docker', 'pull', ruby_image_name
|
41
|
+
end
|
42
|
+
|
43
|
+
desc "Build iruby-test docker image"
|
44
|
+
task :build_test_image => 'tmp' do
|
45
|
+
require 'erb'
|
46
|
+
dockerfile_content = ERB.new(File.read('ci/Dockerfile.main.erb')).result(binding)
|
47
|
+
File.write('tmp/Dockerfile', dockerfile_content)
|
48
|
+
sh 'docker', 'build', '-t', iruby_test_image_name, '-f', 'tmp/Dockerfile', '.'
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'before_install script for CI with Docker'
|
52
|
+
task :before_install => :pull_ruby_image
|
53
|
+
task :before_install => :build_test_base_image
|
54
|
+
|
55
|
+
desc 'install script for CI with Docker'
|
56
|
+
task :install => :build_test_image
|
57
|
+
|
58
|
+
desc 'main script for CI with Docker'
|
59
|
+
task :script do
|
60
|
+
volumes = ['-v', "#{Dir.pwd}:/iruby"] if ENV['attach_pwd']
|
61
|
+
sh 'docker', 'run', '--rm', '-it', *volumes,
|
62
|
+
iruby_test_image_name, 'bash', 'run-test.sh'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/test/integration_test.rb
CHANGED
@@ -1,40 +1,52 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
require '
|
2
|
+
require 'pty'
|
3
3
|
require 'expect'
|
4
4
|
|
5
|
-
class IntegrationTest < IRubyTest
|
5
|
+
class IRubyTest::IntegrationTest < IRubyTest::TestBase
|
6
6
|
def setup
|
7
|
-
|
7
|
+
$expect_verbose = false # make true if you want to dump the output of iruby console
|
8
|
+
|
9
|
+
@in, @out, pid = PTY.spawn('bin/iruby --simple-prompt')
|
10
|
+
@waiter = Thread.start { Process.waitpid(pid) }
|
8
11
|
expect 'In [', 30
|
9
12
|
expect '1'
|
10
13
|
expect ']:'
|
11
14
|
end
|
12
15
|
|
13
16
|
def teardown
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@process.kill
|
17
|
+
@in.close
|
18
|
+
@out.close
|
19
|
+
@waiter.join
|
18
20
|
end
|
19
21
|
|
20
22
|
def write(input)
|
21
|
-
@
|
23
|
+
@out.puts input
|
22
24
|
end
|
23
25
|
|
24
|
-
def expect(pattern, timeout =
|
25
|
-
assert @
|
26
|
+
def expect(pattern, timeout = 10)
|
27
|
+
assert @in.expect(pattern, timeout), "#{pattern} expected, but timeout"
|
28
|
+
end
|
29
|
+
|
30
|
+
def wait_prompt
|
31
|
+
expect 'In ['
|
32
|
+
expect ']:'
|
26
33
|
end
|
27
34
|
|
28
35
|
def test_interaction
|
36
|
+
skip "This test too much unstable"
|
37
|
+
|
29
38
|
write '"Hello, world!"'
|
30
39
|
expect '"Hello, world!"'
|
31
40
|
|
41
|
+
wait_prompt
|
32
42
|
write 'puts "Hello!"'
|
33
43
|
expect 'Hello!'
|
34
44
|
|
45
|
+
wait_prompt
|
35
46
|
write '12 + 12'
|
36
47
|
expect '24'
|
37
48
|
|
49
|
+
wait_prompt
|
38
50
|
write 'ls'
|
39
51
|
expect 'self.methods'
|
40
52
|
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'iruby/command'
|
3
|
+
|
4
|
+
module IRubyTest
|
5
|
+
class CommandTest < TestBase
|
6
|
+
def test_with_empty_argv
|
7
|
+
with_env('JUPYTER_DATA_DIR' => nil,
|
8
|
+
'IPYTHONDIR' => nil) do
|
9
|
+
assert_output(nil, /\A\z/) do
|
10
|
+
@command = IRuby::Command.new([])
|
11
|
+
kernel_dir = File.join(IRuby::Jupyter.kernelspec_dir, 'ruby')
|
12
|
+
assert_equal(kernel_dir, @command.kernel_dir)
|
13
|
+
assert_equal(File.join(kernel_dir, 'kernel.json'), @command.kernel_file)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_with_JUPYTER_DATA_DIR
|
19
|
+
Dir.mktmpdir do |tmpdir|
|
20
|
+
with_env('JUPYTER_DATA_DIR' => tmpdir,
|
21
|
+
'IPYTHONDIR' => nil) do
|
22
|
+
assert_output(nil, /\A\z/) do
|
23
|
+
@command = IRuby::Command.new([])
|
24
|
+
kernel_dir = File.join(tmpdir, 'kernels', 'ruby')
|
25
|
+
assert_equal(kernel_dir, @command.kernel_dir)
|
26
|
+
assert_equal(File.join(kernel_dir, 'kernel.json'), @command.kernel_file)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_with_IPYTHONDIR
|
33
|
+
Dir.mktmpdir do |tmpdir|
|
34
|
+
with_env('JUPYTER_DATA_DIR' => nil,
|
35
|
+
'IPYTHONDIR' => tmpdir) do
|
36
|
+
assert_output(nil, /IPYTHONDIR is deprecated\. Use JUPYTER_DATA_DIR instead\./) do
|
37
|
+
@command = IRuby::Command.new([])
|
38
|
+
kernel_dir = File.join(tmpdir, 'kernels', 'ruby')
|
39
|
+
assert_equal(kernel_dir, @command.kernel_dir)
|
40
|
+
assert_equal(File.join(kernel_dir, 'kernel.json'), @command.kernel_file)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_with_JUPYTER_DATA_DIR_and_IPYTHONDIR
|
47
|
+
Dir.mktmpdir do |tmpdir|
|
48
|
+
Dir.mktmpdir do |tmpdir2|
|
49
|
+
with_env('JUPYTER_DATA_DIR' => tmpdir,
|
50
|
+
'IPYTHONDIR' => tmpdir2) do
|
51
|
+
assert_output(nil, /both JUPYTER_DATA_DIR and IPYTHONDIR are supplied; IPYTHONDIR is ignored\./) do
|
52
|
+
@command = IRuby::Command.new([])
|
53
|
+
kernel_dir = File.join(tmpdir, 'kernels', 'ruby')
|
54
|
+
assert_equal(kernel_dir, @command.kernel_dir)
|
55
|
+
assert_equal(File.join(kernel_dir, 'kernel.json'), @command.kernel_file)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_with_ipython_dir_option
|
63
|
+
Dir.mktmpdir do |tmpdir|
|
64
|
+
with_env('JUPYTER_DATA_DIR' => nil,
|
65
|
+
'IPYTHONDIR' => nil) do
|
66
|
+
assert_output(nil, /--ipython-dir is deprecated\. Use JUPYTER_DATA_DIR environment variable instead\./) do
|
67
|
+
@command = IRuby::Command.new(%W[--ipython-dir=#{tmpdir}])
|
68
|
+
kernel_dir = File.join(tmpdir, 'kernels', 'ruby')
|
69
|
+
assert_equal(kernel_dir, @command.kernel_dir)
|
70
|
+
assert_equal(File.join(kernel_dir, 'kernel.json'), @command.kernel_file)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_with_JUPYTER_DATA_DIR_and_ipython_dir_option
|
77
|
+
Dir.mktmpdir do |tmpdir|
|
78
|
+
Dir.mktmpdir do |tmpdir2|
|
79
|
+
with_env('JUPYTER_DATA_DIR' => tmpdir,
|
80
|
+
'IPYTHONDIR' => nil) do
|
81
|
+
assert_output(nil, /both JUPYTER_DATA_DIR and --ipython-dir are supplied; --ipython-dir is ignored\./) do
|
82
|
+
@command = IRuby::Command.new(%W[--ipython-dir=#{tmpdir2}])
|
83
|
+
kernel_dir = File.join(tmpdir, 'kernels', 'ruby')
|
84
|
+
assert_equal(kernel_dir, @command.kernel_dir)
|
85
|
+
assert_equal(File.join(kernel_dir, 'kernel.json'), @command.kernel_file)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_register_when_there_is_kernel_in_ipython_dir
|
93
|
+
Dir.mktmpdir do |tmpdir|
|
94
|
+
Dir.mktmpdir do |tmpdir2|
|
95
|
+
with_env('JUPYTER_DATA_DIR' => nil,
|
96
|
+
'IPYTHONDIR' => nil,
|
97
|
+
'HOME' => tmpdir2) do
|
98
|
+
ignore_warning do
|
99
|
+
@command = IRuby::Command.new(["register", "--ipython-dir=~/.ipython"])
|
100
|
+
assert_equal("#{tmpdir2}/.ipython/kernels/ruby/kernel.json", @command.kernel_file)
|
101
|
+
@command.run
|
102
|
+
assert(File.file?("#{tmpdir2}/.ipython/kernels/ruby/kernel.json"))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
with_env('JUPYTER_DATA_DIR' => nil,
|
107
|
+
'IPYTHONDIR' => nil,
|
108
|
+
'HOME' => tmpdir2) do
|
109
|
+
@command = IRuby::Command.new(["register"])
|
110
|
+
assert_output(nil, /IRuby kernel file already exists in the deprecated IPython's data directory\.\nUsing --force, you can replace the old kernel file with the new one in Jupyter's data directory\./) do
|
111
|
+
@command.run
|
112
|
+
end
|
113
|
+
assert(File.file?(File.join(@command.ipython_kernel_dir, 'kernel.json')))
|
114
|
+
refute(File.file?(@command.kernel_file))
|
115
|
+
|
116
|
+
@command = IRuby::Command.new(["register", "--force"])
|
117
|
+
assert_output(nil, nil) do
|
118
|
+
@command.run
|
119
|
+
end
|
120
|
+
refute(File.exist?(@command.ipython_kernel_dir))
|
121
|
+
assert(File.file?(@command.kernel_file))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_register_and_unregister_with_JUPYTER_DATA_DIR
|
128
|
+
Dir.mktmpdir do |tmpdir|
|
129
|
+
Dir.mktmpdir do |tmpdir2|
|
130
|
+
with_env('JUPYTER_DATA_DIR' => tmpdir,
|
131
|
+
'IPYTHONDIR' => nil,
|
132
|
+
'HOME' => tmpdir2) do
|
133
|
+
assert_output(nil, nil) do
|
134
|
+
@command = IRuby::Command.new(['register'])
|
135
|
+
kernel_dir = File.join(tmpdir, 'kernels', 'ruby')
|
136
|
+
kernel_file = File.join(kernel_dir, 'kernel.json')
|
137
|
+
assert(!File.file?(kernel_file))
|
138
|
+
|
139
|
+
@command.run
|
140
|
+
assert(File.file?(kernel_file))
|
141
|
+
|
142
|
+
@command = IRuby::Command.new(['unregister'])
|
143
|
+
@command.run
|
144
|
+
assert(!File.file?(kernel_file))
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_register_and_unregister_with_JUPYTER_DATA_DIR_when_there_is_kernel_in_ipython_dir
|
152
|
+
Dir.mktmpdir do |tmpdir|
|
153
|
+
Dir.mktmpdir do |tmpdir2|
|
154
|
+
with_env('HOME' => tmpdir2) do
|
155
|
+
ignore_warning do
|
156
|
+
@command = IRuby::Command.new(["register", "--ipython-dir=~/.ipython"])
|
157
|
+
assert_equal("#{tmpdir2}/.ipython/kernels/ruby/kernel.json", @command.kernel_file)
|
158
|
+
@command.run
|
159
|
+
assert(File.file?("#{tmpdir2}/.ipython/kernels/ruby/kernel.json"))
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
with_env('JUPYTER_DATA_DIR' => tmpdir,
|
164
|
+
'IPYTHONDIR' => nil,
|
165
|
+
'HOME' => tmpdir2) do
|
166
|
+
@command = IRuby::Command.new(["register"])
|
167
|
+
assert_output(nil, /IRuby kernel file already exists in the deprecated IPython's data directory\.\nUsing --force, you can replace the old kernel file with the new one in Jupyter's data directory\./) do
|
168
|
+
@command.run
|
169
|
+
end
|
170
|
+
assert(File.file?(File.join(@command.ipython_kernel_dir, 'kernel.json')))
|
171
|
+
refute(File.file?(@command.kernel_file))
|
172
|
+
|
173
|
+
@command = IRuby::Command.new(["register", "--force"])
|
174
|
+
assert_output(nil, nil) do
|
175
|
+
@command.run
|
176
|
+
end
|
177
|
+
refute(File.file?(File.join(@command.ipython_kernel_dir, 'kernel.json')))
|
178
|
+
assert(File.file?(@command.kernel_file))
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_register_and_unregister_with_IPYTHONDIR
|
185
|
+
Dir.mktmpdir do |tmpdir|
|
186
|
+
Dir.mktmpdir do |tmpdir2|
|
187
|
+
with_env('JUPYTER_DATA_DIR' => nil,
|
188
|
+
'IPYTHONDIR' => tmpdir,
|
189
|
+
'HOME' => tmpdir2) do
|
190
|
+
ignore_warning do
|
191
|
+
@command = IRuby::Command.new(['register'])
|
192
|
+
kernel_dir = File.join(tmpdir, 'kernels', 'ruby')
|
193
|
+
kernel_file = File.join(kernel_dir, 'kernel.json')
|
194
|
+
assert(!File.file?(kernel_file))
|
195
|
+
|
196
|
+
@command.run
|
197
|
+
assert(File.file?(kernel_file))
|
198
|
+
|
199
|
+
@command = IRuby::Command.new(['unregister'])
|
200
|
+
@command.run
|
201
|
+
assert(!File.file?(kernel_file))
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|