stamina 0.3.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.
Files changed (80) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGELOG.md +22 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +33 -0
  5. data/LICENCE.md +22 -0
  6. data/Manifest.txt +16 -0
  7. data/README.md +78 -0
  8. data/Rakefile +23 -0
  9. data/bin/adl2dot +12 -0
  10. data/bin/classify +12 -0
  11. data/bin/redblue +12 -0
  12. data/bin/rpni +12 -0
  13. data/example/adl/automaton.adl +49 -0
  14. data/example/adl/sample.adl +53 -0
  15. data/example/basic/characteristic_sample.adl +32 -0
  16. data/example/basic/target.adl +9 -0
  17. data/example/competition/31_test.adl +1500 -0
  18. data/example/competition/31_training.adl +1759 -0
  19. data/lib/stamina.rb +19 -0
  20. data/lib/stamina/adl.rb +298 -0
  21. data/lib/stamina/automaton.rb +1237 -0
  22. data/lib/stamina/automaton/walking.rb +336 -0
  23. data/lib/stamina/classifier.rb +37 -0
  24. data/lib/stamina/command/adl2dot_command.rb +73 -0
  25. data/lib/stamina/command/classify_command.rb +57 -0
  26. data/lib/stamina/command/redblue_command.rb +58 -0
  27. data/lib/stamina/command/rpni_command.rb +58 -0
  28. data/lib/stamina/command/stamina_command.rb +79 -0
  29. data/lib/stamina/errors.rb +20 -0
  30. data/lib/stamina/induction/commons.rb +170 -0
  31. data/lib/stamina/induction/redblue.rb +264 -0
  32. data/lib/stamina/induction/rpni.rb +188 -0
  33. data/lib/stamina/induction/union_find.rb +377 -0
  34. data/lib/stamina/input_string.rb +123 -0
  35. data/lib/stamina/loader.rb +0 -0
  36. data/lib/stamina/markable.rb +42 -0
  37. data/lib/stamina/sample.rb +190 -0
  38. data/lib/stamina/version.rb +14 -0
  39. data/stamina.gemspec +190 -0
  40. data/stamina.noespec +35 -0
  41. data/tasks/debug_mail.rake +78 -0
  42. data/tasks/debug_mail.txt +13 -0
  43. data/tasks/gem.rake +68 -0
  44. data/tasks/spec_test.rake +79 -0
  45. data/tasks/unit_test.rake +77 -0
  46. data/tasks/yard.rake +51 -0
  47. data/test/stamina/adl_test.rb +491 -0
  48. data/test/stamina/automaton_additional_test.rb +190 -0
  49. data/test/stamina/automaton_classifier_test.rb +155 -0
  50. data/test/stamina/automaton_test.rb +1092 -0
  51. data/test/stamina/automaton_to_dot_test.rb +64 -0
  52. data/test/stamina/automaton_walking_test.rb +206 -0
  53. data/test/stamina/exit.rb +3 -0
  54. data/test/stamina/induction/induction_test.rb +70 -0
  55. data/test/stamina/induction/redblue_mergesamestatebug_expected.adl +19 -0
  56. data/test/stamina/induction/redblue_mergesamestatebug_pta.dot +64 -0
  57. data/test/stamina/induction/redblue_mergesamestatebug_sample.adl +9 -0
  58. data/test/stamina/induction/redblue_test.rb +83 -0
  59. data/test/stamina/induction/redblue_universal_expected.adl +4 -0
  60. data/test/stamina/induction/redblue_universal_sample.adl +5 -0
  61. data/test/stamina/induction/rpni_inria_expected.adl +7 -0
  62. data/test/stamina/induction/rpni_inria_sample.adl +9 -0
  63. data/test/stamina/induction/rpni_test.rb +129 -0
  64. data/test/stamina/induction/rpni_test_pta.dot +22 -0
  65. data/test/stamina/induction/rpni_universal_expected.adl +4 -0
  66. data/test/stamina/induction/rpni_universal_sample.adl +4 -0
  67. data/test/stamina/induction/union_find_test.rb +124 -0
  68. data/test/stamina/input_string_test.rb +323 -0
  69. data/test/stamina/markable_test.rb +70 -0
  70. data/test/stamina/randdfa.adl +66 -0
  71. data/test/stamina/sample.adl +4 -0
  72. data/test/stamina/sample_classify_test.rb +149 -0
  73. data/test/stamina/sample_test.rb +218 -0
  74. data/test/stamina/small_dfa.dot +16 -0
  75. data/test/stamina/small_dfa.gif +0 -0
  76. data/test/stamina/small_nfa.dot +18 -0
  77. data/test/stamina/small_nfa.gif +0 -0
  78. data/test/stamina/stamina_test.rb +69 -0
  79. data/test/test_all.rb +7 -0
  80. metadata +279 -0
@@ -0,0 +1,4 @@
1
+ 1 2
2
+ 0 true true
3
+ 0 0 a
4
+ 0 0 b
@@ -0,0 +1,5 @@
1
+ +
2
+ + a b b
3
+ + a
4
+ + a a a a a
5
+ + a a a
@@ -0,0 +1,7 @@
1
+ 2 4
2
+ 0 true true
3
+ 1 false false
4
+ 0 0 a
5
+ 0 1 b
6
+ 1 1 a
7
+ 1 0 b
@@ -0,0 +1,9 @@
1
+ +
2
+ + a
3
+ + b b
4
+ + b b a
5
+ + b a a b
6
+ + b a a a b a
7
+ - b
8
+ - a b
9
+ - a b a
@@ -0,0 +1,129 @@
1
+ require File.join(File.dirname(__FILE__), "induction_test")
2
+ module Stamina
3
+ module Induction
4
+ class RPNITest < Stamina::Induction::InductionTest
5
+ include Stamina::Induction::Commons
6
+
7
+ # Factors a ready to be used RPNI instance with an initial UnionFind.
8
+ def rpni(ufds)
9
+ rpni = RPNI.new(:verbose => false)
10
+ rpni.instance_eval do
11
+ @ufds = ufds
12
+ end
13
+ rpni
14
+ end
15
+
16
+ # Returns index-th state of the PTA
17
+ def s(index)
18
+ @pta.ith_state(index)
19
+ end
20
+
21
+ def test_compatible_merge_and_determinize_without_determinize
22
+ rpni = rpni(factor_ufds)
23
+ assert_equal true, rpni.merge_and_determinize(0, 4)
24
+ assert_equal [0, 1, 2, 3, 0, 5, 6, 7, 8, 9], rpni.ufds.to_a
25
+ end
26
+
27
+ def test_compatible_merge_and_determinize_with_one_determinize
28
+ rpni = rpni(factor_ufds)
29
+ assert_equal true, rpni.merge_and_determinize(2, 7)
30
+ assert_equal [0, 1, 2, 3, 4, 5, 6, 2, 5, 6], rpni.ufds.to_a
31
+ end
32
+
33
+ def test_incompatible_merge_and_determinize_without_determinize
34
+ rpni = rpni(factor_ufds)
35
+ assert_equal false, rpni.merge_and_determinize(0, 1)
36
+ assert_equal [0, 0, 2, 3, 4, 5, 6, 7, 8, 9], rpni.ufds.to_a
37
+ end
38
+
39
+ def test_incompatible_merge_and_determinize_with_two_determinize
40
+ rpni = rpni(factor_ufds)
41
+ assert_equal false, rpni.merge_and_determinize(5, 0)
42
+ assert_equal [0, 1, 2, 3, 4, 0, 6, 2, 0, 9], rpni.ufds.to_a
43
+ end
44
+
45
+ def execution_step(rpni, i, j, success, expected=nil)
46
+ before = rpni.ufds.to_a
47
+ assert_equal success, rpni.successfull_merge_or_nothing(i, j)
48
+ if success
49
+ assert_equal(expected, rpni.ufds.to_a) if expected
50
+ else
51
+ assert_equal before, rpni.ufds.to_a
52
+ end
53
+ end
54
+
55
+ def test_step_by_step_whole_execution
56
+ rpni = rpni(factor_ufds)
57
+ execution_step(rpni,1,0,false)
58
+ execution_step(rpni,2,0,true,[0, 1, 0, 3, 4, 1, 0, 4, 8, 9])
59
+ execution_step(rpni,3,0,false)
60
+ execution_step(rpni,3,1,true,[0, 1, 0, 1, 4, 1, 0, 4, 8, 9])
61
+ execution_step(rpni,4,0,true,[0, 1, 0, 1, 0, 1, 0, 0, 1, 0])
62
+
63
+ ufds = factor_ufds
64
+ rpni = rpni(ufds)
65
+ assert_equal [0, 1, 0, 1, 0, 1, 0, 0, 1, 0], rpni.main(ufds).to_a
66
+ end
67
+
68
+ def test_main_whole_execution
69
+ ufds = factor_ufds
70
+ rpni = rpni(ufds)
71
+ assert_equal [0, 1, 0, 1, 0, 1, 0, 0, 1, 0], rpni.main(ufds).to_a
72
+ end
73
+
74
+ def test_execute_whole_execution
75
+ expected = Stamina::ADL.parse_automaton <<-EOF
76
+ 2 4
77
+ 0 true true
78
+ 1 false false
79
+ 0 0 b
80
+ 0 1 a
81
+ 1 0 b
82
+ 1 1 a
83
+ EOF
84
+ dfa = RPNI.execute(@sample)
85
+ assert_equal true, @sample.correctly_classified_by?(dfa)
86
+ assert_equal @sample.signature, dfa.signature(@sample)
87
+ assert_nil equivalent?(expected, dfa)
88
+ end
89
+
90
+ def test_on_dedicated_examples
91
+ here = File.dirname(__FILE__)
92
+ Dir["#{here}/rpni_*_sample.adl"].each do |sample_file|
93
+ name = (/^rpni_(.*?)_sample.adl$/.match(File.basename(sample_file)))[1]
94
+ sample = Stamina::ADL.parse_sample_file(sample_file)
95
+ expected = Stamina::ADL.parse_automaton_file(File.join(here, "rpni_#{name}_expected.adl"))
96
+ assert sample.correctly_classified_by?(expected)
97
+ dfa = RPNI.execute(sample)
98
+ assert sample.correctly_classified_by?(dfa)
99
+ assert_equal sample.signature, dfa.signature(sample)
100
+ assert_nil equivalent?(expected, dfa)
101
+ end
102
+ end
103
+
104
+ # Tests on characteristic sample
105
+ def test_on_public_characteristic_example
106
+ example_folder = File.join(File.dirname(__FILE__), '..', '..', '..', 'example', 'basic')
107
+ sample = Stamina::ADL.parse_sample_file(File.join(example_folder, 'characteristic_sample.adl'))
108
+ rpnied = Stamina::Induction::RPNI.execute(sample)
109
+ assert_equal 4, rpnied.state_count
110
+ s0, = rpnied.initial_state
111
+ s1 = rpnied.dfa_step(s0, 'b')
112
+ s2 = rpnied.dfa_step(s0, 'a')
113
+ s3 = rpnied.dfa_step(s2, 'b')
114
+ assert_equal true, s0.accepting?
115
+ assert_equal true, s3.accepting?
116
+ assert_equal false, s1.accepting?
117
+ assert_equal false, s2.accepting?
118
+ assert_equal s1, s1.dfa_step('a')
119
+ assert_equal s1, s1.dfa_step('b')
120
+ assert_equal s2, s2.dfa_step('a')
121
+ assert_equal s3, s2.dfa_step('b')
122
+ assert_equal s3, s3.dfa_step('b')
123
+ assert_equal s0, s3.dfa_step('a')
124
+ assert_equal sample.signature, rpnied.signature(sample)
125
+ end
126
+
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,22 @@
1
+ digraph G {
2
+ graph [rankdir="LR"];
3
+ 0 [color="green" shape="doublecircle" style="filled"];
4
+ 1 [color="red" shape="circle" style="filled"];
5
+ 2 [color="black" shape="circle" style="filled" fillcolor="white"];
6
+ 3 [color="red" shape="circle" style="filled"];
7
+ 4 [color="black" shape="doublecircle" style="filled" fillcolor="white"];
8
+ 5 [color="black" shape="circle" style="filled" fillcolor="white"];
9
+ 6 [color="black" shape="doublecircle" style="filled" fillcolor="white"];
10
+ 7 [color="black" shape="circle" style="filled" fillcolor="white"];
11
+ 8 [color="red" shape="circle" style="filled"];
12
+ 9 [color="black" shape="doublecircle" style="filled" fillcolor="white"];
13
+ 0 -> 1 [label="a"];
14
+ 1 -> 3 [label="a"];
15
+ 1 -> 4 [label="b"];
16
+ 0 -> 2 [label="b"];
17
+ 2 -> 5 [label="a"];
18
+ 5 -> 7 [label="b"];
19
+ 7 -> 8 [label="a"];
20
+ 7 -> 9 [label="b"];
21
+ 2 -> 6 [label="b"];
22
+ }
@@ -0,0 +1,4 @@
1
+ 1 2
2
+ 0 true true
3
+ 0 0 a
4
+ 0 0 b
@@ -0,0 +1,4 @@
1
+ + a b b a b a a a a a a
2
+ + a b b a b a a a a a a a a a a
3
+
4
+
@@ -0,0 +1,124 @@
1
+ require 'test/unit'
2
+ require 'stamina/induction/union_find'
3
+ module Stamina
4
+ module Induction
5
+ class UnionFindTest < Test::Unit::TestCase
6
+
7
+ def assert_whole_find_is(expected, ufds)
8
+ 0.upto(expected.size-1) do |i|
9
+ assert_equal expected[i], ufds.find(i)
10
+ end
11
+ end
12
+
13
+ def test_initially
14
+ ufds = UnionFind.new(5)
15
+ assert_equal 5, ufds.size
16
+ 0.upto(ufds.size-1) do |i|
17
+ assert_equal i, ufds.find(i)
18
+ assert_equal true, ufds.leader?(i)
19
+ end
20
+ end
21
+
22
+ def test_one_union
23
+ ufds = UnionFind.new(5)
24
+ ufds.union(3,0)
25
+ assert_whole_find_is [0, 1, 2, 0, 4], ufds
26
+ assert_equal true, ufds.leader?(0)
27
+ assert_equal false, ufds.leader?(3)
28
+
29
+ ufds = UnionFind.new(5)
30
+ ufds.union(0,3)
31
+ assert_whole_find_is [0, 1, 2, 0, 4], ufds
32
+ end
33
+
34
+ def test_two_unions
35
+ ufds = UnionFind.new(5)
36
+ ufds.union(3,0)
37
+ ufds.union(4,3)
38
+ assert_whole_find_is [0, 1, 2, 0, 0], ufds
39
+ assert_equal true, ufds.leader?(0)
40
+ assert_equal false, ufds.leader?(3)
41
+ assert_equal false, ufds.leader?(4)
42
+ end
43
+
44
+ def test_three_unions
45
+ ufds = UnionFind.new(5)
46
+ ufds.union(3,0)
47
+ ufds.union(1,2)
48
+ ufds.union(2,4)
49
+ assert_equal true, ufds.leader?(0)
50
+ assert_equal true, ufds.leader?(1)
51
+ assert_equal false, ufds.leader?(2)
52
+ assert_equal false, ufds.leader?(3)
53
+ assert_equal false, ufds.leader?(4)
54
+ end
55
+
56
+ def test_union_supports_identity_union
57
+ ufds = UnionFind.new(5)
58
+ ufds.union(0,0)
59
+ assert_whole_find_is [0, 1, 2, 3, 4], ufds
60
+ ufds.union(1,0)
61
+ assert_whole_find_is [0, 0, 2, 3, 4], ufds
62
+ ufds.union(1,0)
63
+ assert_whole_find_is [0, 0, 2, 3, 4], ufds
64
+ ufds.union(0,1)
65
+ assert_whole_find_is [0, 0, 2, 3, 4], ufds
66
+ end
67
+
68
+ def test_dup
69
+ ufds = UnionFind.new(5)
70
+ ufds.union(3,0)
71
+ copy = ufds.dup
72
+ (0...5).each {|i| assert_equal ufds.find(i), copy.find(i)}
73
+ copy.union(4,3)
74
+ assert_equal 0, copy.find(4)
75
+ assert_equal 4, ufds.find(4)
76
+ end
77
+
78
+ def test_transactional_support
79
+ ufds = UnionFind.new(5)
80
+ ufds.save_point
81
+ ufds.union(3,0)
82
+ assert_whole_find_is [0, 1, 2, 0, 4], ufds
83
+ ufds.commit
84
+ assert_whole_find_is [0, 1, 2, 0, 4], ufds
85
+ ufds.save_point
86
+ ufds.union(4,3)
87
+ assert_whole_find_is [0, 1, 2, 0, 0], ufds
88
+ ufds.rollback
89
+ assert_whole_find_is [0, 1, 2, 0, 4], ufds
90
+ end
91
+
92
+ def test_validity_of_rdoc_example
93
+ # create a union-find for 10 elements
94
+ ufds = Stamina::Induction::UnionFind.new(10) do |index|
95
+ # each element will be associated with a hash with data of interest:
96
+ # smallest element, greatest element and concatenation of names
97
+ {:smallest => index, :greatest => index, :names => index.to_s}
98
+ end
99
+
100
+ # each element is its own leader
101
+ assert_equal true, (0...10).all?{|s| ufds.leader?(s)}
102
+ assert_equal false, (0...10).all?{|s| ufds.slave?(s)}
103
+
104
+ # and their respective group number are the element indices themselve
105
+ assert_equal [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], ufds.to_a
106
+
107
+ # now, let merge 4 with 0
108
+ ufds.union(0, 4) do |d0, d4|
109
+ {:smallest => d0[:smallest] < d4[:smallest] ? d0[:smallest] : d4[:smallest],
110
+ :greatest => d0[:smallest] > d4[:smallest] ? d0[:smallest] : d4[:smallest],
111
+ :names => d0[:names] + " " + d4[:names]}
112
+ end
113
+
114
+ # let see what happens on group numbers
115
+ assert_equal [0, 1, 2, 3, 0, 5, 6, 7, 8, 9], ufds.to_a
116
+
117
+ # let now have a look on mergeable_data of the group of 0 (same result for 4)
118
+ expected = {:smallest => 0, :greatest => 4, :names => "0 4"}
119
+ assert_equal expected, ufds.mergeable_data(0)
120
+ end
121
+
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,323 @@
1
+ require 'test/unit'
2
+ require 'stamina/input_string'
3
+ module Stamina
4
+
5
+ # Tests InputString class
6
+ class InputStringTest < Test::Unit::TestCase
7
+
8
+ # Tests on empty string
9
+ def test_on_empty_string
10
+ # with empty array of symbols, positively labeled
11
+ s = InputString.new([], true)
12
+ assert_equal(0, s.size)
13
+ assert_equal(true, s.empty?)
14
+ assert_equal(true, s.lambda?)
15
+ assert_equal([], s.symbols)
16
+ assert_equal(true, s.symbols.frozen?)
17
+ assert_equal(true, s.positive?)
18
+ assert_equal(false, s.negative?)
19
+ assert_equal(false, s.unlabeled?)
20
+ assert_equal(true, s.label)
21
+
22
+ # with empty array of symbols, negatively labeled
23
+ s = InputString.new([], false)
24
+ assert_equal(0, s.size)
25
+ assert_equal(true, s.empty?)
26
+ assert_equal(true, s.lambda?)
27
+ assert_equal([], s.symbols)
28
+ assert_equal(true, s.symbols.frozen?)
29
+ assert_equal(false, s.positive?)
30
+ assert_equal(true, s.negative?)
31
+ assert_equal(false, s.unlabeled?)
32
+ assert_equal(false, s.label)
33
+
34
+ # with empty array of symbols, unlabeled
35
+ s = InputString.new([], nil)
36
+ assert_equal(0, s.size)
37
+ assert_equal(true, s.empty?)
38
+ assert_equal(true, s.lambda?)
39
+ assert_equal([], s.symbols)
40
+ assert_equal(true, s.symbols.frozen?)
41
+ assert_equal(false, s.positive?)
42
+ assert_equal(false, s.negative?)
43
+ assert_equal(true, s.unlabeled?)
44
+ assert_equal(nil, s.label)
45
+
46
+ # with empty string, positively labeled
47
+ s = InputString.new('', true)
48
+ assert_equal(0, s.size)
49
+ assert_equal(true, s.lambda?)
50
+ assert_equal(true, s.empty?)
51
+ assert_equal([], s.symbols)
52
+ assert_equal(true, s.symbols.frozen?)
53
+ assert_equal(true, s.positive?)
54
+ assert_equal(false, s.negative?)
55
+ assert_equal(false, s.unlabeled?)
56
+
57
+ # with empty string, negatively labeled
58
+ s = InputString.new('', false)
59
+ assert_equal(0, s.size)
60
+ assert_equal(true, s.lambda?)
61
+ assert_equal(true, s.empty?)
62
+ assert_equal([], s.symbols)
63
+ assert_equal(true, s.symbols.frozen?)
64
+ assert_equal(false, s.positive?)
65
+ assert_equal(true, s.negative?)
66
+ assert_equal(false, s.unlabeled?)
67
+
68
+ # with empty string, unlabeled
69
+ s = InputString.new('', nil)
70
+ assert_equal(0, s.size)
71
+ assert_equal(true, s.lambda?)
72
+ assert_equal(true, s.empty?)
73
+ assert_equal([], s.symbols)
74
+ assert_equal(true, s.symbols.frozen?)
75
+ assert_equal(false, s.positive?)
76
+ assert_equal(false, s.negative?)
77
+ assert_equal(true, s.unlabeled?)
78
+
79
+ # with empty string with trailing whitespaces, positively labeled
80
+ s = InputString.new(" ", true)
81
+ assert_equal(0, s.size)
82
+ assert_equal(true, s.lambda?)
83
+ assert_equal(true, s.empty?)
84
+ assert_equal([], s.symbols)
85
+ assert_equal(true, s.symbols.frozen?)
86
+ assert_equal(true, s.positive?)
87
+ assert_equal(false, s.negative?)
88
+ assert_equal(false, s.unlabeled?)
89
+
90
+ # with empty string with trailing whitespaces, negatively labeled
91
+ s = InputString.new(" ", false)
92
+ assert_equal(0, s.size)
93
+ assert_equal(true, s.lambda?)
94
+ assert_equal(true, s.empty?)
95
+ assert_equal([], s.symbols)
96
+ assert_equal(true, s.symbols.frozen?)
97
+ assert_equal(false, s.positive?)
98
+ assert_equal(true, s.negative?)
99
+ assert_equal(false, s.unlabeled?)
100
+
101
+ # with empty string with trailing whitespaces, unlabeled
102
+ s = InputString.new(" ", nil)
103
+ assert_equal(0, s.size)
104
+ assert_equal(true, s.lambda?)
105
+ assert_equal(true, s.empty?)
106
+ assert_equal([], s.symbols)
107
+ assert_equal(true, s.symbols.frozen?)
108
+ assert_equal(false, s.positive?)
109
+ assert_equal(false, s.negative?)
110
+ assert_equal(true, s.unlabeled?)
111
+
112
+ # with empty string with trailing whitespaces, negatively labeled
113
+ s = InputString.new(" \n \t \t\n ", false)
114
+ assert_equal(0, s.size)
115
+ assert_equal(true, s.empty?)
116
+ assert_equal([], s.symbols)
117
+ end
118
+
119
+ # Tests with a string of only one character
120
+ def test_on_one_character_string
121
+ # with array of symbols, positively labeled
122
+ s = InputString.new(['a'], true)
123
+ assert_equal(1, s.size)
124
+ assert_equal(false, s.empty?)
125
+ assert_equal(false, s.lambda?)
126
+ assert_equal(['a'], s.symbols)
127
+ assert_equal(true, s.symbols.frozen?)
128
+ assert_equal(true, s.positive?)
129
+ assert_equal(false, s.negative?)
130
+ assert_equal(false, s.unlabeled?)
131
+ assert_equal(true, s.label)
132
+
133
+ # with empty array of symbols, negatively labeled
134
+ s = InputString.new(['a'], false)
135
+ assert_equal(1, s.size)
136
+ assert_equal(false, s.empty?)
137
+ assert_equal(['a'], s.symbols)
138
+ assert_equal(true, s.symbols.frozen?)
139
+ assert_equal(false, s.positive?)
140
+ assert_equal(true, s.negative?)
141
+ assert_equal(false, s.label)
142
+
143
+ # with empty array of symbols, unlabeled
144
+ s = InputString.new(['a'], nil)
145
+ assert_equal(1, s.size)
146
+ assert_equal(false, s.empty?)
147
+ assert_equal(['a'], s.symbols)
148
+ assert_equal(true, s.symbols.frozen?)
149
+ assert_equal(false, s.positive?)
150
+ assert_equal(false, s.negative?)
151
+ assert_equal(true, s.unlabeled?)
152
+ assert_equal(nil, s.label)
153
+
154
+ # with empty string, positively labeled
155
+ s = InputString.new('a', true)
156
+ assert_equal(1, s.size)
157
+ assert_equal(false, s.empty?)
158
+ assert_equal(['a'], s.symbols)
159
+ assert_equal(true, s.symbols.frozen?)
160
+ assert_equal(true, s.positive?)
161
+ assert_equal(false, s.negative?)
162
+
163
+ # with empty string, negatively labeled
164
+ s = InputString.new('a', false)
165
+ assert_equal(1, s.size)
166
+ assert_equal(false, s.empty?)
167
+ assert_equal(['a'], s.symbols)
168
+ assert_equal(true, s.symbols.frozen?)
169
+ assert_equal(false, s.positive?)
170
+ assert_equal(true, s.negative?)
171
+
172
+ # with empty string with trailing whitespaces, positively labeled
173
+ s = InputString.new("a ", true)
174
+ assert_equal(1, s.size)
175
+ assert_equal(false, s.empty?)
176
+ assert_equal(['a'], s.symbols)
177
+
178
+ # with empty string with trailing whitespaces, positively labeled
179
+ s = InputString.new(" a", true)
180
+ assert_equal(1, s.size)
181
+ assert_equal(false, s.empty?)
182
+ assert_equal(['a'], s.symbols)
183
+
184
+ # with empty string with trailing whitespaces, positively labeled
185
+ s = InputString.new(" \na \t \n", true)
186
+ assert_equal(1, s.size)
187
+ assert_equal(false, s.empty?)
188
+ assert_equal(['a'], s.symbols)
189
+ end
190
+
191
+ def test_negate
192
+ assert_equal InputString.new([], true), InputString.new([], false).negate
193
+ assert_equal InputString.new([], false), InputString.new([], true).negate
194
+ assert_equal InputString.new([], nil), InputString.new([], nil).negate
195
+ assert_equal InputString.new(['a'], true), InputString.new(['a'], false).negate
196
+ assert_equal InputString.new(['a'], false), InputString.new(['a'], true).negate
197
+ assert_equal InputString.new(['a'], nil), InputString.new(['a'], nil).negate
198
+ end
199
+
200
+ # Tests on a small size string.
201
+ def test_on_small_size_string
202
+ s = InputString.new(['a', 'b', 'c', 'a'], true)
203
+ assert_equal(false, s.empty?)
204
+ assert_equal(4, s.size)
205
+ assert_equal(['a', 'b', 'c', 'a'], s.symbols)
206
+ assert_equal(true, s.positive?)
207
+
208
+ s = InputString.new('a b c a', false)
209
+ assert_equal(false, s.empty?)
210
+ assert_equal(4, s.size)
211
+ assert_equal(['a', 'b', 'c', 'a'], s.symbols)
212
+ assert_equal(false, s.positive?)
213
+
214
+ s = InputString.new('a b c a', nil)
215
+ assert_equal(false, s.empty?)
216
+ assert_equal(4, s.size)
217
+ assert_equal(['a', 'b', 'c', 'a'], s.symbols)
218
+ assert_equal(true, s.unlabeled?)
219
+
220
+ s = InputString.new('a b c a', false)
221
+ assert_equal(false, s.empty?)
222
+ assert_equal(4, s.size)
223
+ assert_equal(['a', 'b', 'c', 'a'], s.symbols)
224
+
225
+ s = InputString.new(" a b c a\t", true)
226
+ assert_equal(false, s.empty?)
227
+ assert_equal(4, s.size)
228
+ assert_equal(['a', 'b', 'c', 'a'], s.symbols)
229
+ end
230
+
231
+ # Tests that s.symbols.dup returns a modifiable array
232
+ def test_symbols_duplication_may_be_modified
233
+ s = InputString.new([''], true)
234
+ assert_equal(false, s.symbols.dup.frozen?)
235
+
236
+ s = InputString.new(['a' 'b' 'c' 'a'], true)
237
+ assert_equal(false, s.symbols.dup.frozen?)
238
+
239
+ s = InputString.new('', true)
240
+ assert_equal(false, s.symbols.dup.frozen?)
241
+
242
+ s = InputString.new('a b c a', true)
243
+ assert_equal(false, s.symbols.dup.frozen?)
244
+ end
245
+
246
+ # Tests InputString#==
247
+ def test_equality
248
+ s = InputString.new([], true)
249
+ assert_equal(s, InputString.new([], true))
250
+ assert_equal(s, InputString.new('', true))
251
+ assert_equal(s, InputString.new(' ', true))
252
+ assert_not_equal(s, InputString.new([], false))
253
+ assert_not_equal(s, InputString.new(['a'], false))
254
+ assert_not_equal(s, InputString.new([], nil))
255
+
256
+ s = InputString.new([], false)
257
+ assert_equal(s, InputString.new([], false))
258
+ assert_equal(s, InputString.new('', false))
259
+ assert_equal(s, InputString.new(' ', false))
260
+ assert_not_equal(s, InputString.new([], true))
261
+ assert_not_equal(s, InputString.new(['a'], true))
262
+ assert_not_equal(s, InputString.new([], nil))
263
+
264
+ s = InputString.new([], nil)
265
+ assert_equal(s, InputString.new([], nil))
266
+ assert_equal(s, InputString.new('', nil))
267
+ assert_not_equal(s, InputString.new([], true))
268
+ assert_not_equal(s, InputString.new(['a'], true))
269
+ assert_not_equal(s, InputString.new([], false))
270
+ assert_not_equal(s, InputString.new(['a'], false))
271
+
272
+ s = InputString.new('a b a b', true)
273
+ assert_equal(s, InputString.new("a b \n a b", true))
274
+ assert_equal(s, InputString.new(['a', 'b', 'a', 'b'], true))
275
+ assert_not_equal(s, InputString.new(['a', 'b', 'a', 'b'], false))
276
+ assert_not_equal(s, InputString.new(['a', 'b', 'a'], true))
277
+ assert_not_equal(s, InputString.new([], true))
278
+ end
279
+
280
+ def test_equality_2
281
+ assert InputString.new('+', true)==InputString.new('+', true)
282
+ assert InputString.new('+ a b', true)==InputString.new('+ a b', true)
283
+
284
+ strings = [InputString.new('+', true), InputString.new('+', true)]
285
+ assert_equal 1, strings.uniq.size
286
+ end
287
+
288
+ # Tests that input string accept other objects than strings as symbols
289
+ def test_input_string_accept_any_symbol_object
290
+ s = InputString.new([1, 2], true)
291
+ assert_equal(2, s.size)
292
+ assert_equal([1, 2], s.symbols)
293
+ end
294
+
295
+ def test_input_string_may_be_used_as_hash_key
296
+ str = InputString.new('a b a b', true)
297
+ neg = InputString.new('a b a b', false)
298
+ unl = InputString.new('a b a b', nil)
299
+ h = {}
300
+ h[str] = 1
301
+ assert h.has_key?(str)
302
+ assert_equal 1, h[str]
303
+ assert !h.has_key?(neg)
304
+ assert !h.has_key?(unl)
305
+ h[neg] = 2
306
+ assert h.has_key?(str)
307
+ assert_equal 1, h[str]
308
+ assert h.has_key?(neg)
309
+ assert_equal 2, h[neg]
310
+ assert !h.has_key?(unl)
311
+ h[unl] = 3
312
+ assert h.has_key?(str)
313
+ assert_equal 1, h[str]
314
+ assert h.has_key?(neg)
315
+ assert_equal 2, h[neg]
316
+ assert h.has_key?(unl)
317
+ assert_equal 3, h[unl]
318
+ end
319
+
320
+ end # class InputStringTest
321
+
322
+ end # module Stamina
323
+