stamina 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
+