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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ubuntu.yml +69 -0
  3. data/CHANGES.md +219 -0
  4. data/Gemfile +0 -2
  5. data/LICENSE +1 -1
  6. data/README.md +81 -62
  7. data/Rakefile +10 -10
  8. data/ci/Dockerfile.main.erb +1 -3
  9. data/iruby.gemspec +13 -19
  10. data/lib/iruby.rb +6 -6
  11. data/lib/iruby/backend.rb +38 -10
  12. data/lib/iruby/command.rb +2 -6
  13. data/lib/iruby/display.rb +216 -81
  14. data/lib/iruby/event_manager.rb +40 -0
  15. data/lib/iruby/formatter.rb +3 -3
  16. data/lib/iruby/input.rb +6 -6
  17. data/lib/iruby/input/autoload.rb +1 -1
  18. data/lib/iruby/input/builder.rb +4 -4
  19. data/lib/iruby/input/button.rb +2 -2
  20. data/lib/iruby/input/cancel.rb +1 -1
  21. data/lib/iruby/input/checkbox.rb +3 -3
  22. data/lib/iruby/input/date.rb +3 -3
  23. data/lib/iruby/input/field.rb +2 -2
  24. data/lib/iruby/input/file.rb +3 -3
  25. data/lib/iruby/input/form.rb +6 -6
  26. data/lib/iruby/input/label.rb +4 -4
  27. data/lib/iruby/input/multiple.rb +10 -10
  28. data/lib/iruby/input/popup.rb +2 -2
  29. data/lib/iruby/input/radio.rb +6 -6
  30. data/lib/iruby/input/select.rb +8 -8
  31. data/lib/iruby/input/textarea.rb +1 -1
  32. data/lib/iruby/input/widget.rb +2 -2
  33. data/lib/iruby/jupyter.rb +1 -0
  34. data/lib/iruby/kernel.rb +157 -29
  35. data/lib/iruby/ostream.rb +27 -10
  36. data/lib/iruby/session.rb +1 -0
  37. data/lib/iruby/session_adapter.rb +7 -3
  38. data/lib/iruby/session_adapter/pyzmq_adapter.rb +11 -10
  39. data/lib/iruby/session_adapter/test_adapter.rb +49 -0
  40. data/lib/iruby/utils.rb +15 -0
  41. data/lib/iruby/version.rb +1 -1
  42. data/run-test.sh +1 -1
  43. data/test/helper.rb +136 -0
  44. data/test/integration_test.rb +1 -2
  45. data/test/iruby/backend_test.rb +37 -0
  46. data/test/iruby/command_test.rb +0 -1
  47. data/test/iruby/display_test.rb +188 -0
  48. data/test/iruby/event_manager_test.rb +92 -0
  49. data/test/iruby/jupyter_test.rb +0 -1
  50. data/test/iruby/kernel_test.rb +185 -0
  51. data/test/iruby/mime_test.rb +50 -0
  52. data/test/iruby/multi_logger_test.rb +0 -4
  53. data/test/iruby/session_adapter/cztop_adapter_test.rb +1 -1
  54. data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +1 -1
  55. data/test/iruby/session_adapter/session_adapter_test_base.rb +1 -3
  56. data/test/iruby/session_adapter_test.rb +42 -67
  57. data/test/iruby/session_test.rb +10 -15
  58. data/test/run-test.rb +19 -0
  59. metadata +74 -62
  60. data/.travis.yml +0 -41
  61. data/CHANGES +0 -143
  62. data/CONTRIBUTORS +0 -19
  63. data/lib/iruby/session/rbczmq.rb +0 -72
  64. data/lib/iruby/session_adapter/rbczmq_adapter.rb +0 -33
  65. data/test/iruby/session_adapter/rbczmq_adapter_test.rb +0 -37
  66. 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
@@ -1,3 +1,3 @@
1
1
  module IRuby
2
- VERSION = '0.4.0'
2
+ VERSION = '0.7.1'
3
3
  end
data/run-test.sh CHANGED
@@ -4,7 +4,7 @@ set -ex
4
4
 
5
5
  export PYTHON=python3
6
6
 
7
- ADAPTERS="cztop rbczmq ffi-rzmq pyzmq"
7
+ ADAPTERS="cztop ffi-rzmq pyzmq"
8
8
 
9
9
  for adapter in $ADAPTERS; do
10
10
  export IRUBY_TEST_SESSION_ADAPTER_NAME=$adapter
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
@@ -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
- skip "This test too much unstable"
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
@@ -1,4 +1,3 @@
1
- require 'test_helper'
2
1
  require 'iruby/command'
3
2
 
4
3
  module IRubyTest
@@ -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