iruby 0.2.9 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ubuntu.yml +62 -0
  3. data/CHANGES +64 -0
  4. data/Gemfile +3 -1
  5. data/LICENSE +1 -1
  6. data/README.md +120 -92
  7. data/Rakefile +36 -10
  8. data/ci/Dockerfile.base.erb +41 -0
  9. data/ci/Dockerfile.main.erb +7 -0
  10. data/ci/requirements.txt +1 -0
  11. data/docker/setup.sh +15 -0
  12. data/docker/test.sh +7 -0
  13. data/iruby.gemspec +13 -18
  14. data/lib/iruby.rb +13 -6
  15. data/lib/iruby/backend.rb +38 -9
  16. data/lib/iruby/command.rb +68 -12
  17. data/lib/iruby/display.rb +81 -41
  18. data/lib/iruby/event_manager.rb +40 -0
  19. data/lib/iruby/formatter.rb +3 -3
  20. data/lib/iruby/input.rb +6 -6
  21. data/lib/iruby/input/README.ipynb +55 -3
  22. data/lib/iruby/input/README.md +299 -0
  23. data/lib/iruby/input/autoload.rb +3 -2
  24. data/lib/iruby/input/builder.rb +4 -4
  25. data/lib/iruby/input/button.rb +2 -2
  26. data/lib/iruby/input/cancel.rb +1 -1
  27. data/lib/iruby/input/checkbox.rb +22 -4
  28. data/lib/iruby/input/date.rb +17 -6
  29. data/lib/iruby/input/field.rb +5 -4
  30. data/lib/iruby/input/file.rb +3 -3
  31. data/lib/iruby/input/form.rb +6 -6
  32. data/lib/iruby/input/label.rb +9 -3
  33. data/lib/iruby/input/multiple.rb +76 -0
  34. data/lib/iruby/input/popup.rb +5 -2
  35. data/lib/iruby/input/radio.rb +18 -6
  36. data/lib/iruby/input/select.rb +26 -12
  37. data/lib/iruby/input/textarea.rb +2 -1
  38. data/lib/iruby/input/widget.rb +2 -2
  39. data/lib/iruby/jupyter.rb +77 -0
  40. data/lib/iruby/kernel.rb +171 -31
  41. data/lib/iruby/ostream.rb +29 -8
  42. data/lib/iruby/session.rb +116 -0
  43. data/lib/iruby/session/{rbczmq.rb → cztop.rb} +21 -19
  44. data/lib/iruby/session/ffi_rzmq.rb +1 -1
  45. data/lib/iruby/session_adapter.rb +72 -0
  46. data/lib/iruby/session_adapter/cztop_adapter.rb +45 -0
  47. data/lib/iruby/session_adapter/ffirzmq_adapter.rb +55 -0
  48. data/lib/iruby/session_adapter/pyzmq_adapter.rb +77 -0
  49. data/lib/iruby/session_adapter/test_adapter.rb +49 -0
  50. data/lib/iruby/utils.rb +13 -2
  51. data/lib/iruby/version.rb +1 -1
  52. data/run-test.sh +12 -0
  53. data/tasks/ci.rake +65 -0
  54. data/test/helper.rb +133 -0
  55. data/test/integration_test.rb +22 -11
  56. data/test/iruby/backend_test.rb +37 -0
  57. data/test/iruby/command_test.rb +207 -0
  58. data/test/iruby/event_manager_test.rb +92 -0
  59. data/test/iruby/jupyter_test.rb +27 -0
  60. data/test/iruby/kernel_test.rb +153 -0
  61. data/test/iruby/mime_test.rb +43 -0
  62. data/test/iruby/multi_logger_test.rb +1 -2
  63. data/test/iruby/session_adapter/cztop_adapter_test.rb +20 -0
  64. data/test/iruby/session_adapter/ffirzmq_adapter_test.rb +20 -0
  65. data/test/iruby/session_adapter/session_adapter_test_base.rb +27 -0
  66. data/test/iruby/session_adapter_test.rb +91 -0
  67. data/test/iruby/session_test.rb +48 -0
  68. data/test/run-test.rb +19 -0
  69. metadata +107 -50
  70. data/.travis.yml +0 -16
  71. data/CONTRIBUTORS +0 -19
  72. data/test/test_helper.rb +0 -5
@@ -2,7 +2,7 @@ begin
2
2
  require 'erector'
3
3
  rescue LoadError
4
4
  raise LoadError, <<-ERROR.gsub(/\s+/,' ')
5
- IRuby::Input requires the erector gem.
5
+ IRuby::Input requires the erector gem.
6
6
  `gem install erector` or add `gem 'erector'`
7
7
  it to your Gemfile to continue.
8
8
  ERROR
@@ -21,4 +21,5 @@ require 'iruby/input/select'
21
21
  require 'iruby/input/checkbox'
22
22
  require 'iruby/input/radio'
23
23
  require 'iruby/input/textarea'
24
- require 'iruby/input/date'
24
+ require 'iruby/input/date'
25
+ require 'iruby/input/multiple'
@@ -21,7 +21,7 @@ module IRuby
21
21
  def html &block
22
22
  add_field Class.new(Widget) {
23
23
  define_method(:widget_html) { instance_eval &block }
24
- }.new
24
+ }.new
25
25
  end
26
26
 
27
27
  def text string
@@ -44,7 +44,7 @@ module IRuby
44
44
  end
45
45
  end
46
46
 
47
- private
47
+ private
48
48
 
49
49
  def process key, &block
50
50
  @processors[key.to_s] = block
@@ -52,14 +52,14 @@ module IRuby
52
52
 
53
53
  def unique_key key
54
54
  @keys ||= []
55
-
55
+
56
56
  if @keys.include? key
57
57
  (2..Float::INFINITY).each do |i|
58
58
  test = "#{key}#{i}"
59
59
  break key = test unless @keys.include? test
60
60
  end
61
61
  end
62
-
62
+
63
63
  @keys << key; key
64
64
  end
65
65
  end
@@ -10,7 +10,7 @@ module IRuby
10
10
  green: 'success',
11
11
  aqua: 'info',
12
12
  orange: 'warning',
13
- red: 'danger',
13
+ red: 'danger',
14
14
  none: 'link'
15
15
  }
16
16
 
@@ -37,7 +37,7 @@ module IRuby
37
37
  def widget_html
38
38
  button(
39
39
  @label || to_label(@key),
40
- type: 'button',
40
+ type: 'button',
41
41
  :'data-iruby-key' => @key,
42
42
  class: "btn btn-#{COLORS[@color]} pull-right #{@js_class}"
43
43
  )
@@ -22,7 +22,7 @@ module IRuby
22
22
  def widget_html
23
23
  button(
24
24
  @label,
25
- type: 'button',
25
+ type: 'button',
26
26
  :'data-dismiss' => 'modal',
27
27
  class: "btn btn-danger pull-right iruby-cancel"
28
28
  )
@@ -1,7 +1,7 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Checkbox < Label
4
- needs :options
4
+ needs :options, :default
5
5
 
6
6
  builder :checkbox do |*args, **params|
7
7
  key = :checkbox
@@ -9,11 +9,24 @@ module IRuby
9
9
 
10
10
  params[:key] = unique_key(key)
11
11
  params[:options] = args
12
+
13
+ params[:default] = case params[:default]
14
+ when false, nil
15
+ []
16
+ when true
17
+ [*params[:options]]
18
+ else
19
+ [*params[:default]]
20
+ end
21
+
12
22
  add_field Checkbox.new(**params)
13
23
  end
14
24
 
15
25
  def widget_css
16
- '.iruby-checkbox-container { margin-left: 10px; }'
26
+ <<-CSS
27
+ .iruby-checkbox.form-control { display: inline-table; }
28
+ .iruby-checkbox .checkbox-inline { margin: 0 15px 0 0; }
29
+ CSS
17
30
  end
18
31
 
19
32
  def widget_js
@@ -30,6 +43,8 @@ module IRuby
30
43
  $(parent).data('iruby-value', null);
31
44
  }
32
45
  });
46
+
47
+ $('.iruby-checkbox input').trigger('change');
33
48
  JS
34
49
  end
35
50
 
@@ -41,9 +56,12 @@ module IRuby
41
56
  widget_label do
42
57
  div **params do
43
58
  @options.each do |option|
44
- label class: 'checkbox-inline' do
59
+ label class: 'checkbox-inline' do
45
60
  input(
46
- name: @key, value: option, type: 'checkbox'
61
+ name: @key,
62
+ value: option,
63
+ type: 'checkbox',
64
+ checked: @default.include?(option)
47
65
  )
48
66
  text option
49
67
  end
@@ -1,26 +1,37 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Date < Field
4
- needs js_class: 'iruby-date'
4
+ needs js_class: 'iruby-date', icon: '📅'
5
5
 
6
6
  builder :date do |key='date', **params|
7
+ params[:default] ||= false
7
8
  params[:key] = unique_key key
9
+
10
+ if params[:default].is_a? Time
11
+ params[:default] = params[:default].strftime('%m/%d/%Y')
12
+ end
13
+
8
14
  add_field Date.new(**params)
15
+
16
+ process params[:key] do |result,key,value|
17
+ result[key.to_sym] = Time.strptime(value,'%m/%d/%Y')
18
+ end
9
19
  end
10
20
 
11
21
  def widget_css
12
- '#ui-datepicker-div { z-index: 2000; }'
22
+ '#ui-datepicker-div { z-index: 2000 !important; }'
13
23
  end
14
24
 
15
- def widget_js
25
+ def widget_js
16
26
  <<-JS
17
27
  $('.iruby-date').datepicker({
28
+ dateFormat: 'mm/dd/yy',
18
29
  onClose: function(date) {
19
- $('.iruby-date').data('iruby-value', date);
20
- }
30
+ $(this).data('iruby-value', date);
31
+ }
21
32
  });
22
33
  JS
23
34
  end
24
35
  end
25
36
  end
26
- end
37
+ end
@@ -1,7 +1,7 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Field < Label
4
- needs :type => 'text', js_class: 'iruby-field'
4
+ needs default: nil, type: 'text', js_class: 'iruby-field'
5
5
 
6
6
  builder :input do |key='input', **params|
7
7
  params[:key] = unique_key key
@@ -17,11 +17,12 @@ module IRuby
17
17
  end
18
18
 
19
19
  def widget_html
20
- widget_label do
20
+ widget_label do
21
21
  input(
22
- type: @type,
22
+ type: @type,
23
23
  :'data-iruby-key' => @key,
24
- class: "form-control #{@js_class}"
24
+ class: "form-control #{@js_class}",
25
+ value: @default
25
26
  )
26
27
  end
27
28
  end
@@ -13,10 +13,10 @@ module IRuby
13
13
 
14
14
  # get rid of Chrome's silly path
15
15
  name = value['name'].sub('C:\\fakepath\\','')
16
-
16
+
17
17
  result[key.to_sym] = {
18
18
  name: name,
19
- data: uri.data,
19
+ data: uri.data,
20
20
  content_type: uri.content_type
21
21
  }
22
22
  end
@@ -46,7 +46,7 @@ module IRuby
46
46
  def widget_html
47
47
  widget_label do
48
48
  input(
49
- type: 'file',
49
+ type: 'file',
50
50
  :'data-iruby-key' => @key,
51
51
  class: 'form-control iruby-file'
52
52
  )
@@ -5,7 +5,7 @@ module IRuby
5
5
  class InputForm < Widget
6
6
  needs :fields, buttons: []
7
7
 
8
- def widget_js
8
+ def widget_js
9
9
  javascript = <<-JS
10
10
  var remove = function () {
11
11
  Jupyter.notebook.kernel.send_input_reply(
@@ -14,7 +14,7 @@ module IRuby
14
14
  })
15
15
  );
16
16
  };
17
-
17
+
18
18
  $("#iruby-form").on("remove", remove);
19
19
 
20
20
  $('#iruby-form').submit(function() {
@@ -33,16 +33,16 @@ module IRuby
33
33
  Jupyter.notebook.kernel.send_input_reply(
34
34
  JSON.stringify({'#{@id}': result})
35
35
  );
36
-
36
+
37
37
  $(this).remove();
38
38
  return false;
39
39
  });
40
40
 
41
41
  $('#iruby-form').keydown(function(event) {
42
- if (event.keyCode == 13 && !event.shiftKey) {
42
+ if (event.keyCode == 13 && !event.shiftKey) {
43
43
  $('#iruby-form').submit();
44
- } else if (event.keyCode == 27) {
45
- $('#iruby-form').remove();
44
+ } else if (event.keyCode == 27) {
45
+ $('#iruby-form').remove();
46
46
  }
47
47
  });
48
48
  JS
@@ -1,13 +1,19 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Label < Widget
4
- needs label: nil
4
+ needs label: nil, icon: nil
5
5
 
6
6
  def widget_label
7
- label = @label || to_label(@key)
8
7
  div class: 'iruby-label input-group' do
9
- span label, class: 'input-group-addon'
8
+ span class: 'input-group-addon' do
9
+ text @label || to_label(@key)
10
+ end
11
+
10
12
  yield
13
+
14
+ if @icon
15
+ span @icon, class: "input-group-addon"
16
+ end
11
17
  end
12
18
  end
13
19
 
@@ -0,0 +1,76 @@
1
+ module IRuby
2
+ module Input
3
+ class Multiple < Label
4
+ needs :options, :default, size: nil
5
+
6
+ builder :multiple do |*args, **params|
7
+ key = :multiple
8
+ key, *args = args if args.first.is_a? Symbol
9
+
10
+ params[:key] = unique_key(key)
11
+ params[:options] = args
12
+
13
+ params[:default] = case params[:default]
14
+ when false, nil
15
+ []
16
+ when true
17
+ [*params[:options]]
18
+ else
19
+ [*params[:default]]
20
+ end
21
+
22
+ add_field Multiple.new(**params)
23
+ end
24
+
25
+ def widget_css
26
+ <<-CSS
27
+ .iruby-multiple {
28
+ display: table;
29
+ min-width: 25%;
30
+ }
31
+ .form-control.iruby-multiple-container {
32
+ display: table;
33
+ }
34
+ CSS
35
+ end
36
+
37
+ def widget_js
38
+ <<-JS
39
+ $('.iruby-multiple').change(function(){
40
+ var multiple = $(this);
41
+ multiple.data('iruby-value', []);
42
+
43
+ multiple.find(':selected').each(function(){
44
+ multiple.data('iruby-value').push($(this).val());
45
+ });
46
+
47
+ if (multiple.data('iruby-value').length == 0) {
48
+ multiple.data('iruby-value', null);
49
+ }
50
+ });
51
+
52
+ $('.iruby-multiple').trigger('change');
53
+ JS
54
+ end
55
+
56
+ def widget_html
57
+ widget_label do
58
+ div class: 'form-control iruby-multiple-container' do
59
+ params = {
60
+ size: @size,
61
+ multiple: true,
62
+ class: 'iruby-multiple',
63
+ :'data-iruby-key' => @key
64
+ }
65
+
66
+ select **params do
67
+ @options.each do |o|
68
+ option o, selected: @default.include?(o)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -21,9 +21,12 @@ module IRuby
21
21
  #{widget_join :widget_js, @form, *@buttons}
22
22
 
23
23
  var popup = $(this);
24
+
24
25
  $('#iruby-form').submit(function() {
25
26
  popup.modal('hide');
26
- })
27
+ });
28
+
29
+ Jupyter.notebook.keyboard_manager.disable();
27
30
  }
28
31
  });
29
32
 
@@ -35,4 +38,4 @@ module IRuby
35
38
  end
36
39
  end
37
40
  end
38
- end
41
+ end
@@ -1,25 +1,34 @@
1
1
  module IRuby
2
2
  module Input
3
3
  class Radio < Label
4
- needs :options
4
+ needs :options, :default
5
5
 
6
6
  builder :radio do |*args, **params|
7
7
  key = :radio
8
8
  key, *args = args if args.first.is_a? Symbol
9
-
9
+
10
10
  params[:key] = unique_key(key)
11
11
  params[:options] = args
12
+ params[:default] ||= false
12
13
  add_field Radio.new(**params)
13
14
  end
14
15
 
16
+ def widget_css
17
+ <<-CSS
18
+ .iruby-radio.form-control { display: inline-table; }
19
+ .iruby-radio .radio-inline { margin: 0 15px 0 0; }
20
+ CSS
21
+ end
22
+
15
23
  def widget_js
16
24
  <<-JS
17
25
  $('.iruby-radio input').change(function(){
18
26
  var parent = $(this).closest('.iruby-radio');
19
- $(parent).data('iruby-value',
27
+ $(parent).data('iruby-value',
20
28
  $(parent).find(':checked').val()
21
29
  );
22
30
  });
31
+ $('.iruby-radio input').trigger('change');
23
32
  JS
24
33
  end
25
34
 
@@ -29,12 +38,15 @@ module IRuby
29
38
  :'data-iruby-value' => @options.first,
30
39
  class: 'iruby-radio form-control'
31
40
  }
32
- widget_label do
41
+ widget_label do
33
42
  div **params do
34
43
  @options.each do |option|
35
- label class: 'radio-inline' do
44
+ label class: 'radio-inline' do
36
45
  input(
37
- name: @key, value: option, type: 'radio'
46
+ name: @key,
47
+ value: option,
48
+ type: 'radio',
49
+ checked: @default == option
38
50
  )
39
51
  text option
40
52
  end