termgui 0.0.4

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 (101) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +14 -0
  3. data/README.md +321 -0
  4. data/lib/termgui.rb +1 -0
  5. data/src/action.rb +58 -0
  6. data/src/box.rb +90 -0
  7. data/src/color.rb +174 -0
  8. data/src/cursor.rb +69 -0
  9. data/src/editor/editor_base.rb +152 -0
  10. data/src/editor/editor_base_handlers.rb +116 -0
  11. data/src/element.rb +61 -0
  12. data/src/element_bounds.rb +111 -0
  13. data/src/element_box.rb +64 -0
  14. data/src/element_render.rb +102 -0
  15. data/src/element_style.rb +51 -0
  16. data/src/emitter.rb +102 -0
  17. data/src/emitter_state.rb +19 -0
  18. data/src/enterable.rb +93 -0
  19. data/src/event.rb +92 -0
  20. data/src/focus.rb +102 -0
  21. data/src/geometry.rb +53 -0
  22. data/src/image.rb +60 -0
  23. data/src/input.rb +85 -0
  24. data/src/input_grab.rb +17 -0
  25. data/src/input_time.rb +97 -0
  26. data/src/key.rb +114 -0
  27. data/src/log.rb +24 -0
  28. data/src/node.rb +117 -0
  29. data/src/node_attributes.rb +27 -0
  30. data/src/node_visit.rb +52 -0
  31. data/src/renderer.rb +119 -0
  32. data/src/renderer_cursor.rb +18 -0
  33. data/src/renderer_draw.rb +28 -0
  34. data/src/renderer_image.rb +31 -0
  35. data/src/renderer_print.rb +40 -0
  36. data/src/screen.rb +96 -0
  37. data/src/screen_element.rb +59 -0
  38. data/src/screen_input.rb +43 -0
  39. data/src/screen_renderer.rb +53 -0
  40. data/src/style.rb +149 -0
  41. data/src/tco/colouring.rb +248 -0
  42. data/src/tco/config.rb +57 -0
  43. data/src/tco/palette.rb +603 -0
  44. data/src/tco/tco_termgui.rb +30 -0
  45. data/src/termgui.rb +29 -0
  46. data/src/util/css.rb +98 -0
  47. data/src/util/css_query.rb +23 -0
  48. data/src/util/easing.rb +364 -0
  49. data/src/util/hash_object.rb +131 -0
  50. data/src/util/imagemagick.rb +27 -0
  51. data/src/util/justify.rb +20 -0
  52. data/src/util/unicode-categories.rb +572 -0
  53. data/src/util/wrap.rb +102 -0
  54. data/src/util.rb +110 -0
  55. data/src/widget/button.rb +33 -0
  56. data/src/widget/checkbox.rb +47 -0
  57. data/src/widget/col.rb +30 -0
  58. data/src/widget/image.rb +106 -0
  59. data/src/widget/inline.rb +40 -0
  60. data/src/widget/input_number.rb +73 -0
  61. data/src/widget/inputbox.rb +85 -0
  62. data/src/widget/label.rb +33 -0
  63. data/src/widget/modal.rb +69 -0
  64. data/src/widget/row.rb +26 -0
  65. data/src/widget/selectbox.rb +100 -0
  66. data/src/widget/textarea.rb +54 -0
  67. data/src/xml/xml.rb +80 -0
  68. data/test/action_test.rb +34 -0
  69. data/test/box_test.rb +15 -0
  70. data/test/css_test.rb +39 -0
  71. data/test/editor/editor_base_test.rb +201 -0
  72. data/test/element_bounds_test.rb +77 -0
  73. data/test/element_box_test.rb +8 -0
  74. data/test/element_render_test.rb +124 -0
  75. data/test/element_style_test.rb +85 -0
  76. data/test/element_test.rb +10 -0
  77. data/test/emitter_test.rb +108 -0
  78. data/test/event_test.rb +19 -0
  79. data/test/focus_test.rb +37 -0
  80. data/test/geometry_test.rb +12 -0
  81. data/test/input_test.rb +47 -0
  82. data/test/key_test.rb +14 -0
  83. data/test/log_test.rb +21 -0
  84. data/test/node_test.rb +105 -0
  85. data/test/performance/performance1.rb +48 -0
  86. data/test/renderer_test.rb +74 -0
  87. data/test/renderer_test_rect.rb +4 -0
  88. data/test/screen_test.rb +58 -0
  89. data/test/style_test.rb +18 -0
  90. data/test/termgui_test.rb +10 -0
  91. data/test/test_all.rb +30 -0
  92. data/test/util_hash_object_test.rb +93 -0
  93. data/test/util_test.rb +26 -0
  94. data/test/widget/checkbox_test.rb +99 -0
  95. data/test/widget/col_test.rb +87 -0
  96. data/test/widget/inline_test.rb +40 -0
  97. data/test/widget/label_test.rb +94 -0
  98. data/test/widget/row_test.rb +40 -0
  99. data/test/wrap_test.rb +11 -0
  100. data/test/xml_test.rb +77 -0
  101. metadata +148 -0
@@ -0,0 +1,77 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/element'
4
+ require_relative '../src/util'
5
+ require_relative '../src/style'
6
+ require_relative '../src/screen'
7
+ require_relative '../src/log'
8
+
9
+ class ElementBoundsTest < Test::Unit::TestCase
10
+ def test_abs
11
+ child2 = Element.new(x: 2, y: 1)
12
+ child1 = Element.new(x: 4, y: 3, children: [child2])
13
+
14
+ assert_equal 2, child2.x
15
+ assert_equal 1, child2.y
16
+ assert_equal 4, child1.x
17
+ assert_equal 3, child1.y
18
+
19
+ assert_equal 6, child2.abs_x
20
+ assert_equal 4, child2.abs_y
21
+ assert_equal 4, child1.abs_x
22
+ assert_equal 3, child1.abs_y
23
+ end
24
+
25
+ def test_abs_percent
26
+ e = Element.new(x: 1, y: 2, width: 16, height: 12)
27
+ e1 = Element.new(x: 0.3, y: 0.2, width: 0.6, height: 0.6)
28
+ e.append_child(e1)
29
+ assert_equal 9, e1.abs_width
30
+ assert_equal 7, e1.abs_height
31
+ assert_equal 4, e1.abs_y
32
+ assert_equal 5, e1.abs_x
33
+ end
34
+
35
+ def test_render_offset
36
+ screen = Screen.new_for_testing(width: 12, height: 7, silent: true)
37
+ screen.append_child Element.new(x: 7, y: 3, width: 7, height: 12, text: 'hello', ch: '·', style: { border: Border.new, padding: Bounds.new(top: 1, left: 2) })
38
+ screen.clear
39
+ screen.render
40
+
41
+ assert_equal(
42
+ ' \n' \
43
+ ' \n' \
44
+ ' \n' \
45
+ ' ┌────\n' \
46
+ ' │····\n' \
47
+ ' │··he\n' \
48
+ ' │····\n', screen.renderer.print
49
+ )
50
+
51
+ screen.offset.left = 5
52
+ screen.clear
53
+ screen.render
54
+ assert_equal(
55
+ ' \n' \
56
+ ' \n' \
57
+ ' \n' \
58
+ ' ┌───────┐ \n' \
59
+ ' │·······│ \n' \
60
+ ' │··hello│ \n' \
61
+ ' │·······│ \n', screen.renderer.print
62
+ )
63
+
64
+ screen.offset.top = 2
65
+ screen.clear
66
+ screen.render
67
+ assert_equal(
68
+ ' \n' \
69
+ ' ┌───────┐ \n' \
70
+ ' │·······│ \n' \
71
+ ' │··hello│ \n' \
72
+ ' │·······│ \n' \
73
+ ' │·······│ \n' \
74
+ ' │·······│ \n', screen.renderer.print
75
+ )
76
+ end
77
+ end
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/element_box'
4
+ require_relative '../src/screen'
5
+ require_relative '../src/element'
6
+
7
+ class ElementBoxTest < Test::Unit::TestCase
8
+ end
@@ -0,0 +1,124 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/element'
4
+ require_relative '../src/util'
5
+ require_relative '../src/style'
6
+ require_relative '../src/screen'
7
+ require_relative '../src/log'
8
+
9
+ class ElementRenderTest < Test::Unit::TestCase
10
+ def test_render
11
+ child2 = Element.new(x: 2, y: 1, width: 2, height: 1, ch: '2')
12
+ child1 = Element.new(x: 4, y: 3, width: 10, height: 8, ch: '1', children: [child2])
13
+ node = Element.new(children: [child1])
14
+ screen = Screen.new_for_testing(width: 16, height: 11)
15
+ node.render screen
16
+ s3 =
17
+ ' \\n' \
18
+ ' \\n' \
19
+ ' \\n' \
20
+ ' 1111111111 \\n' \
21
+ ' 1122111111 \\n' \
22
+ ' 1111111111 \\n' \
23
+ ' 1111111111 \\n' \
24
+ ' 1111111111 \\n' \
25
+ ' 1111111111 \\n' \
26
+ ' 1111111111 \\n' \
27
+ ' 1111111111 \\n' \
28
+ ''
29
+ assert_equal s3, screen.renderer.print
30
+ end
31
+
32
+ def test_render_text1
33
+ screen = Screen.new_for_testing(width: 12, height: 7)
34
+ e = Element.new(x: 1, y: 2, width: 6, height: 3, text: 'hello', ch: '·')
35
+ screen.append_child(e)
36
+ screen.render
37
+ assert_equal(
38
+ ' \\n' \
39
+ ' \\n' \
40
+ ' hello· \\n' \
41
+ ' ······ \\n' \
42
+ ' ······ \\n' \
43
+ ' \\n' \
44
+ ' \\n' \
45
+ '', screen.print
46
+ )
47
+ end
48
+
49
+ def test_render_text2
50
+ screen = Screen.new_for_testing(width: 12, height: 7)
51
+ e = Element.new(x: 1, y: 2, width: 9, height: 3, text: 'hello', ch: '·', style: { padding: Bounds.new(top: 1, left: 2) })
52
+ screen.append_child(e)
53
+ screen.render
54
+ assert_equal(
55
+ ' \\n' \
56
+ ' \\n' \
57
+ ' ········· \\n' \
58
+ ' ··hello·· \\n' \
59
+ ' ········· \\n' \
60
+ ' \\n' \
61
+ ' \\n' \
62
+ '', screen.print
63
+ )
64
+ end
65
+
66
+ def test_render_border
67
+ screen = Screen.new_for_testing(width: 12, height: 9)
68
+ e = Element.new(x: 1, y: 2, width: 6, height: 3, text: 'hello', ch: '·')
69
+ e.style.border = Border.new
70
+ screen.append_child(e)
71
+ screen.render
72
+ assert_equal(
73
+ ' \n' \
74
+ ' \n' \
75
+ ' ┌──────┐ \n' \
76
+ ' │hello·│ \n' \
77
+ ' │······│ \n' \
78
+ ' │······│ \n' \
79
+ ' └──────┘ \n' \
80
+ ' \n' \
81
+ ' \n' \
82
+ '', screen.print
83
+ )
84
+ end
85
+
86
+ def test_render_text_nl
87
+ screen = Screen.new_for_testing(width: 12, height: 7)
88
+ e = Element.new(x: 1, y: 2, width: 6, height: 3, text: 'hello\nworld', ch: '·')
89
+ e.style.border = Border.new
90
+ screen.append_child(e)
91
+ screen.render
92
+ assert_equal(
93
+ ' \n' \
94
+ ' \n' \
95
+ ' ┌──────┐ \n' \
96
+ ' │hello·│ \n' \
97
+ ' │world·│ \n' \
98
+ ' │······│ \n' \
99
+ ' └──────┘ \n' \
100
+ '', screen.print
101
+ )
102
+ end
103
+
104
+ def test_render_text_wrap
105
+ screen = Screen.new_for_testing(width: 16, height: 9)
106
+ e = Element.new(x: 1, y: 1, width: 12, height: 5, text: 'as df rf ty gh fg sdf ed', ch: '·')
107
+ e.style.border = Border.new
108
+ e.style.wrap = true
109
+ screen.append_child(e)
110
+ screen.render
111
+ assert_equal(
112
+ ' \n' \
113
+ ' ┌────────────┐ \n' \
114
+ ' │as df rf ty·│ \n' \
115
+ ' │gh fg sdf ed│ \n' \
116
+ ' │············│ \n' \
117
+ ' │············│ \n' \
118
+ ' │············│ \n' \
119
+ ' └────────────┘ \n' \
120
+ ' \n' \
121
+ '', screen.print
122
+ )
123
+ end
124
+ end
@@ -0,0 +1,85 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/element'
4
+ require_relative '../src/util'
5
+ require_relative '../src/style'
6
+ require_relative '../src/screen'
7
+ require_relative '../src/log'
8
+
9
+ class ElementStyleTest < Test::Unit::TestCase
10
+ def test_constructor_style
11
+ e = Element.new(
12
+ attributes: { focusable: true, focused: false },
13
+ style: {
14
+ focus: Style.new(bg: 'red')
15
+ }
16
+ )
17
+ assert_equal 'red', e.style.focus.bg
18
+ assert_equal true, e.get_attribute('focusable')
19
+ assert_equal true, e.get_attribute(:focusable)
20
+ assert_equal false, e.get_attribute(:focused)
21
+ assert_equal false, e.get_attribute('focused')
22
+ assert_equal nil, e.style.border
23
+ e.style.border = Border.new
24
+ assert_equal Border.new.style, e.style.border.style
25
+ # assert_equal ({ bg: nil,
26
+ # blink: nil,
27
+ # bold: nil,
28
+ # fg: nil,
29
+ # fraktur: nil,
30
+ # framed: nil,
31
+ # inverse: nil,
32
+ # style: 'single',
33
+ # underline: nil }), e.style.border.to_hash
34
+ # assert object_equal({ bg: nil,
35
+ # blink: nil,
36
+ # bold: nil,
37
+ # fg: nil,
38
+ # fraktur: nil,
39
+ # framed: nil,
40
+ # inverse: nil,
41
+ # style: 'single',
42
+ # underline: nil }, e.style.border.to_hash)
43
+
44
+ assert_equal(e.style.focus.bg, 'red')
45
+ end
46
+
47
+ # def test_style_no_focus_if_not_declared
48
+ # e = Element.new
49
+ # assert_equal nil, e.style.focus
50
+ # assert_equal nil, e.style.border
51
+ # end
52
+
53
+ def test_style
54
+ s = Style.new(border: Border.new(style: 'classic', fg: 'red'), fg: 'blue', bg: 'bright_magenta')
55
+ assert_equal 'classic', s.border.style
56
+ assert_equal 'red', s.border.fg
57
+ assert_equal 'blue', s.fg
58
+
59
+ e = Element.new
60
+ e.style = { fg: 'black', bg: 'white' }
61
+ assert_equal 'black', e.style.fg
62
+ assert_equal 'white', e.style.bg
63
+
64
+ e.style = s
65
+ assert_equal 'classic', e.style.border.style
66
+ assert_equal 'red', e.style.border.fg
67
+ assert_equal 'blue', e.style.fg
68
+ end
69
+
70
+ def test_final_style
71
+ e = Element.new(
72
+ attributes: { focusable: true, focused: false },
73
+ style: {
74
+ bg: 'white',
75
+ focus: Style.new(bg: 'red')
76
+ }
77
+ )
78
+ assert_equal 'red', e.style.focus.bg
79
+ assert_equal 'white', e.final_style.bg
80
+ assert_equal false, e.get_attribute('focused')
81
+ e.set_attribute('focused', true)
82
+ assert_equal true, e.get_attribute('focused')
83
+ assert_equal 'red', e.final_style.bg
84
+ end
85
+ end
@@ -0,0 +1,10 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/element'
4
+ require_relative '../src/util'
5
+ require_relative '../src/style'
6
+ require_relative '../src/screen'
7
+ require_relative '../src/log'
8
+
9
+ class ElementTest < Test::Unit::TestCase
10
+ end
@@ -0,0 +1,108 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/emitter'
4
+ require_relative '../src/util'
5
+
6
+ class EmitterTest < Test::Unit::TestCase
7
+ def test_event_emitter
8
+ event_emitter = Emitter.new
9
+ s = ''
10
+ ring_bell = lambda do |_object|
11
+ s = 'ring ring ring'
12
+ end
13
+ # create an event 'doorOpen'
14
+ event_emitter.install(:doorOpen)
15
+ # and subscribe code to event
16
+ event_emitter.subscribe(:doorOpen, ring_bell)
17
+ # to trigger event
18
+ event_emitter.emit(:doorOpen)
19
+ next_tick
20
+ assert_equal 'ring ring ring', s
21
+
22
+ s = ''
23
+ event_emitter.subscribe(:doorOpen, proc { |e| s = e[:msg] })
24
+ event_emitter.emit(:doorOpen, msg: 'hello')
25
+ next_tick
26
+ assert_equal 'hello', s
27
+ end
28
+
29
+ def test_state
30
+ e = Emitter.new
31
+ e.install(:play)
32
+ a = 0
33
+ b = 0
34
+ e.subscribe(:play, proc {
35
+ a += 1
36
+ })
37
+ e.emit(:play)
38
+ assert_equal 1, a
39
+ assert_equal 0, b
40
+ e.emitter_save('a')
41
+ e.emitter_reset
42
+ e.install(:play)
43
+ e.on(:play, proc { b += 1 })
44
+ e.emit(:play)
45
+ assert_equal 1, a
46
+ assert_equal 1, b
47
+ e.emitter_save('b')
48
+
49
+ e.emitter_load('a')
50
+ e.emit(:play)
51
+ assert_equal 2, a
52
+ assert_equal 1, b
53
+
54
+ e.emitter_load('b')
55
+ e.emit(:play)
56
+ assert_equal 2, a
57
+ assert_equal 2, b
58
+ end
59
+
60
+ def test_block
61
+ e = Emitter.new
62
+ e.install(:play)
63
+ a = 0
64
+ b = 0
65
+ e.subscribe(:play) { a += 1 }
66
+ e.on(:play) { b += 1 }
67
+ assert_equal 0, a
68
+ assert_equal 0, b
69
+ e.emit(:play)
70
+ assert_equal 1, a
71
+ assert_equal 1, b
72
+ end
73
+
74
+ def test_unsubscribe
75
+ e = Emitter.new
76
+ e.install(:play)
77
+ a = 0
78
+ b = 0
79
+ s1 = e.subscribe(:play) { a += 1 }
80
+ s2 = e.subscribe(:play) { b += 1 }
81
+ assert_equal 0, a
82
+ assert_equal 0, b
83
+ e.emit(:play)
84
+ assert_equal 1, a
85
+ assert_equal 1, b
86
+ e.unsubscribe(:play, s2)
87
+ e.emit(:play)
88
+ assert_equal 2, a
89
+ assert_equal 1, b
90
+ end
91
+
92
+ def test_once
93
+ e = Emitter.new
94
+ e.install(:play)
95
+ a = 0
96
+ b = 0
97
+ e.subscribe(:play) { a += 1 }
98
+ e.once(:play) { b += 1 }
99
+ assert_equal 0, a
100
+ assert_equal 0, b
101
+ e.emit(:play)
102
+ assert_equal 1, a
103
+ assert_equal 1, b
104
+ e.emit(:play)
105
+ assert_equal 2, a
106
+ assert_equal 1, b
107
+ end
108
+ end
@@ -0,0 +1,19 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/event'
4
+
5
+ class EventManagerTest < Test::Unit::TestCase
6
+ def test_add_key_listener
7
+ e = EventManager.new
8
+ s = 'n'
9
+ e.add_key_listener('q', proc do |ev|
10
+ s = ev.key
11
+ end)
12
+
13
+ e.handle_key(KeyEvent.new('q', 'q'))
14
+ assert_equal s, 'q', 'should notify'
15
+
16
+ e.handle_key(KeyEvent.new('x', 'x'))
17
+ assert_equal s, 'q', 'should not notify'
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/focus'
4
+ require_relative '../src/node'
5
+ require_relative '../src/event'
6
+
7
+ class FocusTest < Test::Unit::TestCase
8
+ def test_next
9
+ c1 = Node.new(
10
+ name: 'child1',
11
+ attributes: { focusable: true }
12
+ )
13
+ c2 = Node.new(
14
+ name: 'child2',
15
+ attributes: { focusable: true }
16
+ )
17
+ root = Node.new(
18
+ text: 'parent',
19
+ children: [c1, c2]
20
+ )
21
+ assert_equal nil, c1.get_attribute(:focused)
22
+ focus = FocusManager.new(root: root, event: EventManager.new)
23
+ times = 0
24
+ focus.add_listener(:focus, proc { |e|
25
+ if times.zero?
26
+ assert_equal e[:focused], c2
27
+ assert_equal e[:previous], c1
28
+ end
29
+ times += 1
30
+ })
31
+ assert_equal true, c1.get_attribute(:focused)
32
+ focus.focus_next
33
+ assert_equal false, c1.get_attribute(:focused)
34
+ assert_equal true, c2.get_attribute(:focused)
35
+ assert_equal times, 1
36
+ end
37
+ end
@@ -0,0 +1,12 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/geometry'
4
+
5
+ class GeometryTest < Test::Unit::TestCase
6
+ def test_bounds
7
+ o = Bounds.new(top: 2, left: 1, right: 3, bottom: 4)
8
+ assert_equal 2, o.top
9
+ o.top = 6
10
+ assert_equal 6, o.top
11
+ end
12
+ end
@@ -0,0 +1,47 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/input'
4
+
5
+ class InputTest < Test::Unit::TestCase
6
+ def test_set_timeout
7
+ i = Input.new
8
+ t = nil
9
+ i.set_timeout(0.1, proc {
10
+ t = 'timeout'
11
+ i.stop
12
+ })
13
+ i.start
14
+ assert_equal t, 'timeout'
15
+ end
16
+
17
+ def test_set_timeout_block
18
+ i = Input.new
19
+ t = nil
20
+ i.set_timeout(0.1) do
21
+ t = 'timeout'
22
+ i.stop
23
+ end
24
+ i.start
25
+ assert_equal t, 'timeout'
26
+ end
27
+
28
+ def test_wait_for
29
+ i = Input.new
30
+ t = nil
31
+ y = nil
32
+ i.wait_for(proc { t == 1 }) do |timeout|
33
+ assert_equal false, timeout
34
+ assert_equal 1, t
35
+ y = 'works'
36
+ i.stop
37
+ end
38
+ i.set_timeout(0.2) do
39
+ t = 1
40
+ end
41
+ assert_equal nil, t
42
+ assert_equal nil, y
43
+ i.start
44
+ assert_equal y, 'works'
45
+ assert_equal 1, t
46
+ end
47
+ end
data/test/key_test.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/key'
4
+
5
+ class KeyTest < Test::Unit::TestCase
6
+ def test_char_to_name
7
+ assert_equal 'C-z', char_to_name('\x1A')
8
+ end
9
+
10
+ def test_name_to_char
11
+ assert_equal '\x1A', name_to_char('C-z')
12
+ assert_equal 'q', name_to_char('q')
13
+ end
14
+ end
data/test/log_test.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/log'
4
+
5
+ class Logger1
6
+ include Log
7
+ def initialize(file = 'log.txt')
8
+ @file = file
9
+ end
10
+ end
11
+
12
+ class LogTest < Test::Unit::TestCase
13
+ def test_log
14
+ `rm -rf tmp_test_log.txt`
15
+ l = Logger1.new 'tmp_test_log.txt'
16
+ l.log(a: [1, 2, { b: false, c: 'hello' }])
17
+ s = File.open('tmp_test_log.txt', 'r').read
18
+ assert_equal "------\n" + "[{:a=>[1, 2, {:b=>false, :c=>\"hello\"}]}]\n", s
19
+ `rm -rf tmp_test_log.txt`
20
+ end
21
+ end
data/test/node_test.rb ADDED
@@ -0,0 +1,105 @@
1
+ require 'test/unit'
2
+ include Test::Unit::Assertions
3
+ require_relative '../src/node'
4
+
5
+ class NodeTest < Test::Unit::TestCase
6
+ def test_children
7
+ n = Node.new
8
+ assert_equal n.children, []
9
+ c = Node.new
10
+ n.append_child c
11
+ assert_equal n.children, [c]
12
+ assert_equal c.children, []
13
+ end
14
+
15
+ def test_visit_node
16
+ n = Node.new(
17
+ text: 'parent',
18
+ children: [
19
+ Node.new(name: 'child1'),
20
+ Node.new(name: 'child2', children: [
21
+ Node.new(name: 'child2.1')
22
+ ])
23
+ ]
24
+ )
25
+ assert_equal 'Node(name: node, children: [Node(name: child1, children: []), ' \
26
+ 'Node(name: child2, children: [Node(name: child2.1, children: [])])])',
27
+ n.to_s
28
+ a = []
29
+ visit_node(n, proc { |child|
30
+ a.push child.name
31
+ false
32
+ })
33
+ assert_equal ['child1', 'child2.1', 'child2', 'node'], a
34
+ end
35
+
36
+ def test_query_by_attribute
37
+ n = Node.new(
38
+ text: 'parent',
39
+ attributes: {
40
+ foo: 'bar'
41
+ },
42
+ children: [
43
+ Node.new(
44
+ name: 'child1',
45
+ attributes: { a: 1.2 }
46
+ ),
47
+ Node.new(
48
+ name: 'child2',
49
+ attributes: { a: 1.2 },
50
+ children: [
51
+ Node.new(
52
+ name: 'child2.1',
53
+ attributes: { a: 1.2 }
54
+ )
55
+ ]
56
+ )
57
+ ]
58
+ )
59
+ result = n.query_by_attribute(:foo, 'bar')
60
+ assert_equal [n], result
61
+ assert_equal ['child1', 'child2.1', 'child2'], n.query_by_attribute(:a, 1.2).map(&:name)
62
+ end
63
+
64
+ def test_query_one_by_attribute
65
+ n = Node.new(
66
+ text: 'parent',
67
+ attributes: {
68
+ },
69
+ children: [
70
+ Node.new(
71
+ name: 'child1',
72
+ attributes: { a: 1.2 }
73
+ ),
74
+ Node.new(
75
+ name: 'child2',
76
+ attributes: { a: 1.2 },
77
+ children: [
78
+ Node.new(
79
+ name: 'child2.1',
80
+ attributes: { a: 1.2 }
81
+ )
82
+ ]
83
+ )
84
+ ]
85
+ )
86
+ result = n.query_one_by_attribute(:a, 1.2)
87
+ assert_equal 'child1', result.name
88
+ end
89
+
90
+ # def test_append_to
91
+ # pend
92
+ # end
93
+
94
+ # def test_insert_children
95
+ # pend
96
+ # end
97
+
98
+ # def test_remove
99
+ # pend
100
+ # end
101
+
102
+ # def test_parent_prop
103
+ # pend
104
+ # end
105
+ end