msgthr.git  about / heads / tags
non-recursive, container-agnostic message threading
blob ee04d549d8d712ec95e254c8c1f331304eb6315d 3800 bytes (raw)
$ git show v1.2.0:test/test_msgthr.rb	# shows this blob on the CLI

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
 
# Copyright (C) 2016 all contributors <msgthr-public@80x24.org>
# License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
require 'test/unit'
require 'msgthr'

class TestMsgthr < Test::Unit::TestCase
  def test_msgthr
    thr = Msgthr.new
    parent_child = ''
    # Note that C is added after B,
    # hence it's message will be empty after adding B
    expected_parent_child = '->B'
    thr.add('a', %w(c b), 'abc')
    thr.add('b', %w(c), 'B') do |parent, child|
      parent_child = "#{parent.msg}->#{child.msg}"
    end
    assert_equal parent_child, expected_parent_child
    thr.add('c', nil, 'c')
    thr.add('D', nil, 'D')
    thr.add('d', %w(missing), 'd')
    rset = thr.thread!
    rootset = thr.order! { |c| c.sort_by!(&:mid) }
    assert_same rset, rootset
    assert_equal %w(D c missing), rootset.map(&:mid)
    assert_equal 'D', rootset[0].msg
    assert_equal %w(b), rootset[1].children.map(&:mid)
    out = ''.b
    thr.walk_thread do |level, container, index|
      msg = container.msg
      summary = msg ? msg : "[missing: <#{container.mid}>]"
      indent = '  ' * level
      out << sprintf("#{indent} % 3d. %s\n", index, summary)
    end
    exp = <<EOF.b
   0. D
   1. c
     0. B
       0. abc
   2. [missing: <missing>]
     0. d
EOF
    assert_equal exp, out
  end

  def test_order_in_thread
    thr = Msgthr.new
    thr.add(1, nil, 'a')
    thr.add(2, [1], 'b')
    thr.thread! do |ary|
      ary.sort_by! do |cont|
        cur = cont.topmost
        cur ? cur : 0
      end
    end
    out = ''
    thr.walk_thread do |level, container, index|
      msg = container.msg
      out << "#{level} [#{index}] #{msg}\n"
    end
    exp = <<EOF.b
0 [0] a
1 [0] b
EOF
    assert_equal exp, out
  end

  def test_out_of_order
    thr = Msgthr.new
    thr.thread!
    assert_raise(Msgthr::StateError) { thr.add(1, nil, 'a') }
    thr.clear # make things good again, following should not raise:
    thr.add(1, nil, 'a')
    thr.thread!
    assert_raise(Msgthr::StateError) { thr.thread! }

    out = []
    thr.walk_thread do |level, container, index|
      msg = container.msg
      out << "#{level} [#{index}] #{msg}"
    end
    assert_equal [ '0 [0] a' ], out
    assert_raise(Msgthr::StateError) { thr.thread! { raise "DO NOT CALL" } }
    assert_raise(Msgthr::StateError) { thr.order! { |_| raise "DO NOT CALL" } }

    # this is legal, even if non-sensical
    thr.clear
    thr.walk_thread { |level, container, index| raise "DO NOT CALL" }
  end

  def test_short_add_to_walk
    thr = Msgthr.new
    thr.add(1, nil, 'a')
    thr.add(2, [1], 'b')
    out = ''
    thr.walk_thread do |level, container, index|
      msg = container.msg
      out << "#{level} [#{index}] #{msg}\n"
    end
    exp = <<EOF.b
0 [0] a
1 [0] b
EOF
    assert_equal exp, out
  end

  def test_add_child_callback
    thr = Msgthr.new
    threads = {}
    [1, 11, 12, 2, 21, 211].each{ |id| threads[id] = [id]}
    my_add = lambda do |id, refs, msg|
      thr.add(id, refs, msg) do |parent, child|
        threads[child.mid] = threads[parent.mid]
      end
    end
    # Create the following structure
    # 1
    #  \
    #  | 1.1
    #  \
    #    1.2
    # 2
    #   \
    #    2.1
    #       \
    #         2.1.1
    my_add.call(1, nil, '1')
    my_add.call(11, [1], '1.1')
    my_add.call(12, [1], '1.2')
    my_add.call(2, nil, '2')
    my_add.call(21, [2], '2.1')
    my_add.call(211, [21], '2.1.1')

    thr.thread!
    thr.rootset.each do |cnt|
      threads[cnt.mid][0] = cnt.msg
    end

    assert_equal threads[1], threads[11]
    assert_equal threads[1], threads[12]
    assert_equal threads[2], threads[21]
    assert_equal threads[2], threads[211]
    assert_equal threads[21], threads[211]
    assert_equal threads[1][0], '1'
    assert_equal threads[2][0], '2'
  end

end

git clone https://80x24.org/msgthr.git