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.
- data/.gemtest +0 -0
 - data/CHANGELOG.md +22 -0
 - data/Gemfile +2 -0
 - data/Gemfile.lock +33 -0
 - data/LICENCE.md +22 -0
 - data/Manifest.txt +16 -0
 - data/README.md +78 -0
 - data/Rakefile +23 -0
 - data/bin/adl2dot +12 -0
 - data/bin/classify +12 -0
 - data/bin/redblue +12 -0
 - data/bin/rpni +12 -0
 - data/example/adl/automaton.adl +49 -0
 - data/example/adl/sample.adl +53 -0
 - data/example/basic/characteristic_sample.adl +32 -0
 - data/example/basic/target.adl +9 -0
 - data/example/competition/31_test.adl +1500 -0
 - data/example/competition/31_training.adl +1759 -0
 - data/lib/stamina.rb +19 -0
 - data/lib/stamina/adl.rb +298 -0
 - data/lib/stamina/automaton.rb +1237 -0
 - data/lib/stamina/automaton/walking.rb +336 -0
 - data/lib/stamina/classifier.rb +37 -0
 - data/lib/stamina/command/adl2dot_command.rb +73 -0
 - data/lib/stamina/command/classify_command.rb +57 -0
 - data/lib/stamina/command/redblue_command.rb +58 -0
 - data/lib/stamina/command/rpni_command.rb +58 -0
 - data/lib/stamina/command/stamina_command.rb +79 -0
 - data/lib/stamina/errors.rb +20 -0
 - data/lib/stamina/induction/commons.rb +170 -0
 - data/lib/stamina/induction/redblue.rb +264 -0
 - data/lib/stamina/induction/rpni.rb +188 -0
 - data/lib/stamina/induction/union_find.rb +377 -0
 - data/lib/stamina/input_string.rb +123 -0
 - data/lib/stamina/loader.rb +0 -0
 - data/lib/stamina/markable.rb +42 -0
 - data/lib/stamina/sample.rb +190 -0
 - data/lib/stamina/version.rb +14 -0
 - data/stamina.gemspec +190 -0
 - data/stamina.noespec +35 -0
 - data/tasks/debug_mail.rake +78 -0
 - data/tasks/debug_mail.txt +13 -0
 - data/tasks/gem.rake +68 -0
 - data/tasks/spec_test.rake +79 -0
 - data/tasks/unit_test.rake +77 -0
 - data/tasks/yard.rake +51 -0
 - data/test/stamina/adl_test.rb +491 -0
 - data/test/stamina/automaton_additional_test.rb +190 -0
 - data/test/stamina/automaton_classifier_test.rb +155 -0
 - data/test/stamina/automaton_test.rb +1092 -0
 - data/test/stamina/automaton_to_dot_test.rb +64 -0
 - data/test/stamina/automaton_walking_test.rb +206 -0
 - data/test/stamina/exit.rb +3 -0
 - data/test/stamina/induction/induction_test.rb +70 -0
 - data/test/stamina/induction/redblue_mergesamestatebug_expected.adl +19 -0
 - data/test/stamina/induction/redblue_mergesamestatebug_pta.dot +64 -0
 - data/test/stamina/induction/redblue_mergesamestatebug_sample.adl +9 -0
 - data/test/stamina/induction/redblue_test.rb +83 -0
 - data/test/stamina/induction/redblue_universal_expected.adl +4 -0
 - data/test/stamina/induction/redblue_universal_sample.adl +5 -0
 - data/test/stamina/induction/rpni_inria_expected.adl +7 -0
 - data/test/stamina/induction/rpni_inria_sample.adl +9 -0
 - data/test/stamina/induction/rpni_test.rb +129 -0
 - data/test/stamina/induction/rpni_test_pta.dot +22 -0
 - data/test/stamina/induction/rpni_universal_expected.adl +4 -0
 - data/test/stamina/induction/rpni_universal_sample.adl +4 -0
 - data/test/stamina/induction/union_find_test.rb +124 -0
 - data/test/stamina/input_string_test.rb +323 -0
 - data/test/stamina/markable_test.rb +70 -0
 - data/test/stamina/randdfa.adl +66 -0
 - data/test/stamina/sample.adl +4 -0
 - data/test/stamina/sample_classify_test.rb +149 -0
 - data/test/stamina/sample_test.rb +218 -0
 - data/test/stamina/small_dfa.dot +16 -0
 - data/test/stamina/small_dfa.gif +0 -0
 - data/test/stamina/small_nfa.dot +18 -0
 - data/test/stamina/small_nfa.gif +0 -0
 - data/test/stamina/stamina_test.rb +69 -0
 - data/test/test_all.rb +7 -0
 - metadata +279 -0
 
    
        data/stamina.noespec
    ADDED
    
    | 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Noe template for ruby gem libraries (https://github.com/blambeau/noe) - short version
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Run 'noe show-spec' and 'noe help show-spec' for additional details.
         
     | 
| 
      
 3 
     | 
    
         
            +
            template-info:
         
     | 
| 
      
 4 
     | 
    
         
            +
              name: "ruby"
         
     | 
| 
      
 5 
     | 
    
         
            +
              version: 1.3.0
         
     | 
| 
      
 6 
     | 
    
         
            +
            variables:
         
     | 
| 
      
 7 
     | 
    
         
            +
              lower: 
         
     | 
| 
      
 8 
     | 
    
         
            +
                stamina
         
     | 
| 
      
 9 
     | 
    
         
            +
              upper:
         
     | 
| 
      
 10 
     | 
    
         
            +
                Stamina
         
     | 
| 
      
 11 
     | 
    
         
            +
              version:
         
     | 
| 
      
 12 
     | 
    
         
            +
                0.3.0
         
     | 
| 
      
 13 
     | 
    
         
            +
              summary: |-
         
     | 
| 
      
 14 
     | 
    
         
            +
                Automaton and Regular Inference Toolkit
         
     | 
| 
      
 15 
     | 
    
         
            +
              description: |-
         
     | 
| 
      
 16 
     | 
    
         
            +
                Stamina is an automaton and regular inference toolkit initially developped for the baseline 
         
     | 
| 
      
 17 
     | 
    
         
            +
                of the Stamina Competition (stamina.chefbe.net).
         
     | 
| 
      
 18 
     | 
    
         
            +
              authors: 
         
     | 
| 
      
 19 
     | 
    
         
            +
                - name: Bernard Lambeau
         
     | 
| 
      
 20 
     | 
    
         
            +
                  email: blambeau@gmail.com
         
     | 
| 
      
 21 
     | 
    
         
            +
              links: 
         
     | 
| 
      
 22 
     | 
    
         
            +
                - http://stamina.chefbe.net/
         
     | 
| 
      
 23 
     | 
    
         
            +
                - http://github.com/blambeau/stamina
         
     | 
| 
      
 24 
     | 
    
         
            +
              dependencies: 
         
     | 
| 
      
 25 
     | 
    
         
            +
                # Rake is required for developers, as usual
         
     | 
| 
      
 26 
     | 
    
         
            +
                - {name: rake,      version: "~> 0.8.7", groups: [development]}
         
     | 
| 
      
 27 
     | 
    
         
            +
                # Bundler is required for developers and is used by the Rakefile
         
     | 
| 
      
 28 
     | 
    
         
            +
                - {name: bundler,   version: "~> 1.0",   groups: [development]}
         
     | 
| 
      
 29 
     | 
    
         
            +
                # RSpec is required to run 'rake spec'. See tasks/spec.rake 
         
     | 
| 
      
 30 
     | 
    
         
            +
                - {name: rspec,     version: "~> 2.4.0", groups: [development]}
         
     | 
| 
      
 31 
     | 
    
         
            +
                # YARD and BlueCloth are required to run 'rake yard'. See tasks/yard.rake 
         
     | 
| 
      
 32 
     | 
    
         
            +
                - {name: yard,      version: "~> 0.6.4", groups: [development]}
         
     | 
| 
      
 33 
     | 
    
         
            +
                - {name: bluecloth, version: "~> 2.0.9", groups: [development]}
         
     | 
| 
      
 34 
     | 
    
         
            +
                # wlang is required to run 'rake debug_mail'. See tasks/debug_mail.rake
         
     | 
| 
      
 35 
     | 
    
         
            +
                - {name: wlang, version: "~> 0.10.1", groups: [development]}
         
     | 
| 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Installs a rake task for debuging the announcement mail.
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # This file installs the 'rake debug_mail' that flushes an announcement mail
         
     | 
| 
      
 4 
     | 
    
         
            +
            # for your library on the standard output. It is automatically generated 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # by Noe from your .noespec file, and should therefore be configured there, 
         
     | 
| 
      
 6 
     | 
    
         
            +
            # under the variables/rake_tasks/debug_mail entry, as illustrated below:
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # variables:
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   rake_tasks:
         
     | 
| 
      
 10 
     | 
    
         
            +
            #     debug_mail:
         
     | 
| 
      
 11 
     | 
    
         
            +
            #       rx_changelog_sections: /^#/
         
     | 
| 
      
 12 
     | 
    
         
            +
            #       nb_changelog_sections: 1
         
     | 
| 
      
 13 
     | 
    
         
            +
            #       ...
         
     | 
| 
      
 14 
     | 
    
         
            +
            #
         
     | 
| 
      
 15 
     | 
    
         
            +
            # If you have specific needs requiring manual intervention on this file, 
         
     | 
| 
      
 16 
     | 
    
         
            +
            # don't forget to set safe-override to false in your noe specification:
         
     | 
| 
      
 17 
     | 
    
         
            +
            # 
         
     | 
| 
      
 18 
     | 
    
         
            +
            # template-info:
         
     | 
| 
      
 19 
     | 
    
         
            +
            #   manifest:
         
     | 
| 
      
 20 
     | 
    
         
            +
            #     tasks/debug_mail.rake:
         
     | 
| 
      
 21 
     | 
    
         
            +
            #       safe-override: false
         
     | 
| 
      
 22 
     | 
    
         
            +
            #
         
     | 
| 
      
 23 
     | 
    
         
            +
            # The mail template used can be found in debug_mail.txt. That file may be
         
     | 
| 
      
 24 
     | 
    
         
            +
            # changed to tune the mail you want to send. If you do so, don't forget to
         
     | 
| 
      
 25 
     | 
    
         
            +
            # add a manifest entry in your .noespec file to avoid overriding you 
         
     | 
| 
      
 26 
     | 
    
         
            +
            # changes. The mail template uses wlang, with parentheses for block 
         
     | 
| 
      
 27 
     | 
    
         
            +
            # delimiters.
         
     | 
| 
      
 28 
     | 
    
         
            +
            #
         
     | 
| 
      
 29 
     | 
    
         
            +
            # template-info:
         
     | 
| 
      
 30 
     | 
    
         
            +
            #   manifest:
         
     | 
| 
      
 31 
     | 
    
         
            +
            #     tasks/debug_mail.txt:
         
     | 
| 
      
 32 
     | 
    
         
            +
            #       safe-override: false
         
     | 
| 
      
 33 
     | 
    
         
            +
            #
         
     | 
| 
      
 34 
     | 
    
         
            +
            begin
         
     | 
| 
      
 35 
     | 
    
         
            +
              require 'wlang'
         
     | 
| 
      
 36 
     | 
    
         
            +
              require 'yaml'
         
     | 
| 
      
 37 
     | 
    
         
            +
              
         
     | 
| 
      
 38 
     | 
    
         
            +
              desc "Debug the release announcement mail"
         
     | 
| 
      
 39 
     | 
    
         
            +
              task :debug_mail do 
         
     | 
| 
      
 40 
     | 
    
         
            +
                # Check that a .noespec file exists
         
     | 
| 
      
 41 
     | 
    
         
            +
                noespec_file = File.expand_path('../../stamina.noespec', __FILE__)
         
     | 
| 
      
 42 
     | 
    
         
            +
                unless File.exists?(noespec_file)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  raise "Unable to find .noespec project file, sorry."
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
                
         
     | 
| 
      
 46 
     | 
    
         
            +
                # Load it as well as variables and options
         
     | 
| 
      
 47 
     | 
    
         
            +
                noespec = YAML::load(File.read(noespec_file))
         
     | 
| 
      
 48 
     | 
    
         
            +
                vars = noespec['variables'] || {}
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                # Changes are taken from CHANGELOG 
         
     | 
| 
      
 51 
     | 
    
         
            +
                logs = Dir[File.expand_path("../../CHANGELOG.*", __FILE__)]
         
     | 
| 
      
 52 
     | 
    
         
            +
                unless logs.size == 1
         
     | 
| 
      
 53 
     | 
    
         
            +
                  abort "Unable to find a changelog file"
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                # Load interesting changesets
         
     | 
| 
      
 57 
     | 
    
         
            +
                changes, end_found = [], 0
         
     | 
| 
      
 58 
     | 
    
         
            +
                File.readlines(logs.first).select{|line|
         
     | 
| 
      
 59 
     | 
    
         
            +
                  if line =~ /^#/
         
     | 
| 
      
 60 
     | 
    
         
            +
                    break if end_found >= 1
         
     | 
| 
      
 61 
     | 
    
         
            +
                    end_found += 1
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  changes << line
         
     | 
| 
      
 64 
     | 
    
         
            +
                }
         
     | 
| 
      
 65 
     | 
    
         
            +
                vars['changes'] = changes.join
         
     | 
| 
      
 66 
     | 
    
         
            +
                
         
     | 
| 
      
 67 
     | 
    
         
            +
                # WLang template
         
     | 
| 
      
 68 
     | 
    
         
            +
                template = File.expand_path('../debug_mail.txt', __FILE__)
         
     | 
| 
      
 69 
     | 
    
         
            +
                
         
     | 
| 
      
 70 
     | 
    
         
            +
                # Let's go!
         
     | 
| 
      
 71 
     | 
    
         
            +
                $stdout << WLang::file_instantiate(template, vars, "wlang/active-text")
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            rescue LoadError 
         
     | 
| 
      
 75 
     | 
    
         
            +
              task :debug_mail do
         
     | 
| 
      
 76 
     | 
    
         
            +
                abort "wlang is not available. Try 'gem install wlang'"
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
    
        data/tasks/gem.rake
    ADDED
    
    | 
         @@ -0,0 +1,68 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Installs rake tasks for gemming and packaging
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # This file installs the 'rake package', 'rake gem' tasks and associates 
         
     | 
| 
      
 4 
     | 
    
         
            +
            # (clobber_package, repackage, ...). It is automatically generated by Noe 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # from your .noespec file, and should therefore be configured there, under 
         
     | 
| 
      
 6 
     | 
    
         
            +
            # the variables/rake_tasks/gem entry, as illustrated below:
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # variables:
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   rake_tasks:
         
     | 
| 
      
 10 
     | 
    
         
            +
            #     gem:
         
     | 
| 
      
 11 
     | 
    
         
            +
            #       package_dir: pkg
         
     | 
| 
      
 12 
     | 
    
         
            +
            #       need_tar: false
         
     | 
| 
      
 13 
     | 
    
         
            +
            #       need_tar_gz: false
         
     | 
| 
      
 14 
     | 
    
         
            +
            #       need_tar_bz2: false
         
     | 
| 
      
 15 
     | 
    
         
            +
            #       need_zip: false
         
     | 
| 
      
 16 
     | 
    
         
            +
            #       ...
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            # If you have specific needs requiring manual intervention on this file, 
         
     | 
| 
      
 19 
     | 
    
         
            +
            # don't forget to set safe-override to false in your noe specification:
         
     | 
| 
      
 20 
     | 
    
         
            +
            # 
         
     | 
| 
      
 21 
     | 
    
         
            +
            # template-info:
         
     | 
| 
      
 22 
     | 
    
         
            +
            #   manifest:
         
     | 
| 
      
 23 
     | 
    
         
            +
            #     tasks/gem.rake:
         
     | 
| 
      
 24 
     | 
    
         
            +
            #       safe-override: false
         
     | 
| 
      
 25 
     | 
    
         
            +
            #
         
     | 
| 
      
 26 
     | 
    
         
            +
            begin
         
     | 
| 
      
 27 
     | 
    
         
            +
              require 'rubygems/package_task'
         
     | 
| 
      
 28 
     | 
    
         
            +
              Gem::PackageTask.new($gemspec) do |t|
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                # Name of the package
         
     | 
| 
      
 31 
     | 
    
         
            +
                t.name = $gemspec.name
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # Version of the package
         
     | 
| 
      
 34 
     | 
    
         
            +
                t.version = $gemspec.version
         
     | 
| 
      
 35 
     | 
    
         
            +
                
         
     | 
| 
      
 36 
     | 
    
         
            +
                # Directory used to store the package files
         
     | 
| 
      
 37 
     | 
    
         
            +
                t.package_dir = "pkg"
         
     | 
| 
      
 38 
     | 
    
         
            +
                
         
     | 
| 
      
 39 
     | 
    
         
            +
                # True if a gzipped tar file (tgz) should be produced
         
     | 
| 
      
 40 
     | 
    
         
            +
                t.need_tar = false
         
     | 
| 
      
 41 
     | 
    
         
            +
                
         
     | 
| 
      
 42 
     | 
    
         
            +
                # True if a gzipped tar file (tar.gz) should be produced
         
     | 
| 
      
 43 
     | 
    
         
            +
                t.need_tar_gz = false
         
     | 
| 
      
 44 
     | 
    
         
            +
                
         
     | 
| 
      
 45 
     | 
    
         
            +
                # True if a bzip2'd tar file (tar.bz2) should be produced
         
     | 
| 
      
 46 
     | 
    
         
            +
                t.need_tar_bz2 = false
         
     | 
| 
      
 47 
     | 
    
         
            +
                
         
     | 
| 
      
 48 
     | 
    
         
            +
                # True if a zip file should be produced (default is false)
         
     | 
| 
      
 49 
     | 
    
         
            +
                t.need_zip = false
         
     | 
| 
      
 50 
     | 
    
         
            +
                
         
     | 
| 
      
 51 
     | 
    
         
            +
                # List of files to be included in the package.
         
     | 
| 
      
 52 
     | 
    
         
            +
                t.package_files = $gemspec.files
         
     | 
| 
      
 53 
     | 
    
         
            +
                
         
     | 
| 
      
 54 
     | 
    
         
            +
                # Tar command for gzipped or bzip2ed archives.
         
     | 
| 
      
 55 
     | 
    
         
            +
                t.tar_command = "tar"
         
     | 
| 
      
 56 
     | 
    
         
            +
                
         
     | 
| 
      
 57 
     | 
    
         
            +
                # Zip command for zipped archives.
         
     | 
| 
      
 58 
     | 
    
         
            +
                t.zip_command = "zip"
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 62 
     | 
    
         
            +
              task :gem do
         
     | 
| 
      
 63 
     | 
    
         
            +
                abort 'rubygems/package_task is not available. You should verify your rubygems installation'
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
              task :package do
         
     | 
| 
      
 66 
     | 
    
         
            +
                abort 'rubygems/package_task is not available. You should verify your rubygems installation'
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,79 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Installs a rake task for for running examples written using rspec.
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # This file installs the 'rake spec_test' (aliased as 'rake spec') as well as
         
     | 
| 
      
 4 
     | 
    
         
            +
            # extends 'rake test' to run spec tests, if any. It is automatically generated 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # by Noe from your .noespec file, and should therefore be configured there, 
         
     | 
| 
      
 6 
     | 
    
         
            +
            # under the variables/rake_tasks/spec_test entry, as illustrated below:
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # variables:
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   rake_tasks:
         
     | 
| 
      
 10 
     | 
    
         
            +
            #     spec_test:
         
     | 
| 
      
 11 
     | 
    
         
            +
            #       pattern: spec/**/*_spec.rb
         
     | 
| 
      
 12 
     | 
    
         
            +
            #       verbose: true
         
     | 
| 
      
 13 
     | 
    
         
            +
            #       rspec_opts: [--color, --backtrace]
         
     | 
| 
      
 14 
     | 
    
         
            +
            #       ...
         
     | 
| 
      
 15 
     | 
    
         
            +
            #
         
     | 
| 
      
 16 
     | 
    
         
            +
            # If you have specific needs requiring manual intervention on this file, 
         
     | 
| 
      
 17 
     | 
    
         
            +
            # don't forget to set safe-override to false in your noe specification:
         
     | 
| 
      
 18 
     | 
    
         
            +
            # 
         
     | 
| 
      
 19 
     | 
    
         
            +
            # template-info:
         
     | 
| 
      
 20 
     | 
    
         
            +
            #   manifest:
         
     | 
| 
      
 21 
     | 
    
         
            +
            #     tasks/spec_test.rake:
         
     | 
| 
      
 22 
     | 
    
         
            +
            #       safe-override: false
         
     | 
| 
      
 23 
     | 
    
         
            +
            #
         
     | 
| 
      
 24 
     | 
    
         
            +
            # This file has been written to conform to RSpec v2.4.0. More information about 
         
     | 
| 
      
 25 
     | 
    
         
            +
            # rspec and options of the rake task defined below can be found on 
         
     | 
| 
      
 26 
     | 
    
         
            +
            # http://relishapp.com/rspec
         
     | 
| 
      
 27 
     | 
    
         
            +
            #
         
     | 
| 
      
 28 
     | 
    
         
            +
            begin
         
     | 
| 
      
 29 
     | 
    
         
            +
              require "rspec/core/rake_task"
         
     | 
| 
      
 30 
     | 
    
         
            +
              desc "Run RSpec code examples"
         
     | 
| 
      
 31 
     | 
    
         
            +
              RSpec::Core::RakeTask.new(:spec_test) do |t|
         
     | 
| 
      
 32 
     | 
    
         
            +
                # Glob pattern to match files.
         
     | 
| 
      
 33 
     | 
    
         
            +
                t.pattern = "spec/**/*_spec.rb"
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                # By default, if there is a Gemfile, the generated command will include
         
     | 
| 
      
 36 
     | 
    
         
            +
                # 'bundle exec'. Set this to true to ignore the presence of a Gemfile, 
         
     | 
| 
      
 37 
     | 
    
         
            +
                # and not add 'bundle exec' to the command.
         
     | 
| 
      
 38 
     | 
    
         
            +
                t.skip_bundler = false
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                # Name of Gemfile to use
         
     | 
| 
      
 41 
     | 
    
         
            +
                t.gemfile = "Gemfile"
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                # Whether or not to fail Rake when an error occurs (typically when 
         
     | 
| 
      
 44 
     | 
    
         
            +
                # examples fail).
         
     | 
| 
      
 45 
     | 
    
         
            +
                t.fail_on_error = true
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                # A message to print to stderr when there are failures.
         
     | 
| 
      
 48 
     | 
    
         
            +
                t.failure_message = nil
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                # Use verbose output. If this is set to true, the task will print the
         
     | 
| 
      
 51 
     | 
    
         
            +
                # executed spec command to stdout.
         
     | 
| 
      
 52 
     | 
    
         
            +
                t.verbose = true
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                # Use rcov for code coverage?
         
     | 
| 
      
 55 
     | 
    
         
            +
                t.rcov = false
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                # Path to rcov.
         
     | 
| 
      
 58 
     | 
    
         
            +
                t.rcov_path = "rcov"
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                # Command line options to pass to rcov. See 'rcov --help' about this
         
     | 
| 
      
 61 
     | 
    
         
            +
                t.rcov_opts = []
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                # Command line options to pass to ruby. See 'ruby --help' about this 
         
     | 
| 
      
 64 
     | 
    
         
            +
                t.ruby_opts = []
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                # Path to rspec
         
     | 
| 
      
 67 
     | 
    
         
            +
                t.rspec_path = "rspec"
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                # Command line options to pass to rspec. See 'rspec --help' about this
         
     | 
| 
      
 70 
     | 
    
         
            +
                t.rspec_opts = ["--color", "--backtrace"]
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
            rescue LoadError => ex
         
     | 
| 
      
 73 
     | 
    
         
            +
              task :spec_test do
         
     | 
| 
      
 74 
     | 
    
         
            +
                abort 'rspec is not available. In order to run spec, you must: gem install rspec'
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
            ensure
         
     | 
| 
      
 77 
     | 
    
         
            +
              task :spec => [:spec_test]
         
     | 
| 
      
 78 
     | 
    
         
            +
              task :test => [:spec_test]
         
     | 
| 
      
 79 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,77 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Installs a rake task for for running unit tests.
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # This file installs the 'rake unit_test' and extends 'rake test' to run unit 
         
     | 
| 
      
 4 
     | 
    
         
            +
            # tests, if any. It is automatically generated by Noe from your .noespec file, 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # and should therefore be configured there, under the variables/rake_tasks/unit_test 
         
     | 
| 
      
 6 
     | 
    
         
            +
            # entry, as illustrated below:
         
     | 
| 
      
 7 
     | 
    
         
            +
            #
         
     | 
| 
      
 8 
     | 
    
         
            +
            # variables:
         
     | 
| 
      
 9 
     | 
    
         
            +
            #   rake_tasks:
         
     | 
| 
      
 10 
     | 
    
         
            +
            #     unit_test:
         
     | 
| 
      
 11 
     | 
    
         
            +
            #       pattern: test/test*.rb
         
     | 
| 
      
 12 
     | 
    
         
            +
            #       verbose: false
         
     | 
| 
      
 13 
     | 
    
         
            +
            #       warning: false
         
     | 
| 
      
 14 
     | 
    
         
            +
            #       ...
         
     | 
| 
      
 15 
     | 
    
         
            +
            #
         
     | 
| 
      
 16 
     | 
    
         
            +
            # If you have specific needs requiring manual intervention on this file, 
         
     | 
| 
      
 17 
     | 
    
         
            +
            # don't forget to set safe-override to false in your noe specification:
         
     | 
| 
      
 18 
     | 
    
         
            +
            # 
         
     | 
| 
      
 19 
     | 
    
         
            +
            # template-info:
         
     | 
| 
      
 20 
     | 
    
         
            +
            #   manifest:
         
     | 
| 
      
 21 
     | 
    
         
            +
            #     tasks/unit_test.rake:
         
     | 
| 
      
 22 
     | 
    
         
            +
            #       safe-override: false
         
     | 
| 
      
 23 
     | 
    
         
            +
            #
         
     | 
| 
      
 24 
     | 
    
         
            +
            # More info about the TestTask and its options can be found on 
         
     | 
| 
      
 25 
     | 
    
         
            +
            # http://rake.rubyforge.org/classes/Rake/TestTask.html
         
     | 
| 
      
 26 
     | 
    
         
            +
            #
         
     | 
| 
      
 27 
     | 
    
         
            +
            begin
         
     | 
| 
      
 28 
     | 
    
         
            +
              require 'rake/testtask'
         
     | 
| 
      
 29 
     | 
    
         
            +
              desc "Run unit tests"
         
     | 
| 
      
 30 
     | 
    
         
            +
              Rake::TestTask.new(:unit_test) do |t|
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                # List of directories to added to $LOAD_PATH before running the
         
     | 
| 
      
 33 
     | 
    
         
            +
                # tests. (default is 'lib')
         
     | 
| 
      
 34 
     | 
    
         
            +
                t.libs = ["lib"]
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                # True if verbose test output desired. (default is false)
         
     | 
| 
      
 37 
     | 
    
         
            +
                t.verbose = false
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                # Test options passed to the test suite.  An explicit TESTOPTS=opts 
         
     | 
| 
      
 40 
     | 
    
         
            +
                # on the command line will override this. (default is NONE)
         
     | 
| 
      
 41 
     | 
    
         
            +
                t.options = nil
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                # Request that the tests be run with the warning flag set.
         
     | 
| 
      
 44 
     | 
    
         
            +
                # E.g. warning=true implies "ruby -w" used to run the tests.
         
     | 
| 
      
 45 
     | 
    
         
            +
                t.warning = false
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                # Glob pattern to match test files. (default is 'test/test*.rb')
         
     | 
| 
      
 48 
     | 
    
         
            +
                t.pattern = "test/test*.rb"
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                # Style of test loader to use.  Options are:
         
     | 
| 
      
 51 
     | 
    
         
            +
                #
         
     | 
| 
      
 52 
     | 
    
         
            +
                # * :rake -- Rake provided test loading script (default).
         
     | 
| 
      
 53 
     | 
    
         
            +
                # * :testrb -- Ruby provided test loading script.
         
     | 
| 
      
 54 
     | 
    
         
            +
                # * :direct -- Load tests using command line loader.
         
     | 
| 
      
 55 
     | 
    
         
            +
                # 
         
     | 
| 
      
 56 
     | 
    
         
            +
                t.loader = :rake
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                # Array of commandline options to pass to ruby when running test 
         
     | 
| 
      
 59 
     | 
    
         
            +
                # loader.
         
     | 
| 
      
 60 
     | 
    
         
            +
                t.ruby_opts = []
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                # Explicitly define the list of test files to be included in a
         
     | 
| 
      
 63 
     | 
    
         
            +
                # test.  +list+ is expected to be an array of file names (a
         
     | 
| 
      
 64 
     | 
    
         
            +
                # FileList is acceptable).  If both +pattern+ and +test_files+ are
         
     | 
| 
      
 65 
     | 
    
         
            +
                # used, then the list of test files is the union of the two.
         
     | 
| 
      
 66 
     | 
    
         
            +
                t.test_files = nil
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
            rescue LoadError => ex
         
     | 
| 
      
 70 
     | 
    
         
            +
              task :unit_test do
         
     | 
| 
      
 71 
     | 
    
         
            +
                abort 'rspec is not available. In order to run spec, you must: gem install rspec'
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
            ensure
         
     | 
| 
      
 74 
     | 
    
         
            +
              desc "Run all tests"
         
     | 
| 
      
 75 
     | 
    
         
            +
              task :test => [:unit_test]
         
     | 
| 
      
 76 
     | 
    
         
            +
            end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
    
        data/tasks/yard.rake
    ADDED
    
    | 
         @@ -0,0 +1,51 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Installs a rake task to generate API documentation using yard.
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            # This file installs the 'rake yard' task. It is automatically generated by Noe from 
         
     | 
| 
      
 4 
     | 
    
         
            +
            # your .noespec file, and should therefore be configured there, under the 
         
     | 
| 
      
 5 
     | 
    
         
            +
            # variables/rake_tasks/yard entry, as illustrated below:
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            # variables:
         
     | 
| 
      
 8 
     | 
    
         
            +
            #   rake_tasks:
         
     | 
| 
      
 9 
     | 
    
         
            +
            #     yard:
         
     | 
| 
      
 10 
     | 
    
         
            +
            #       files: lib/**/*.rb
         
     | 
| 
      
 11 
     | 
    
         
            +
            #       options: []
         
     | 
| 
      
 12 
     | 
    
         
            +
            #       ...
         
     | 
| 
      
 13 
     | 
    
         
            +
            #
         
     | 
| 
      
 14 
     | 
    
         
            +
            # If you have specific needs requiring manual intervention on this file, 
         
     | 
| 
      
 15 
     | 
    
         
            +
            # don't forget to set safe-override to false in your noe specification:
         
     | 
| 
      
 16 
     | 
    
         
            +
            # 
         
     | 
| 
      
 17 
     | 
    
         
            +
            # template-info:
         
     | 
| 
      
 18 
     | 
    
         
            +
            #   manifest:
         
     | 
| 
      
 19 
     | 
    
         
            +
            #     tasks/yard.rake:
         
     | 
| 
      
 20 
     | 
    
         
            +
            #       safe-override: false
         
     | 
| 
      
 21 
     | 
    
         
            +
            #
         
     | 
| 
      
 22 
     | 
    
         
            +
            # This file has been written to conform to yard v0.6.4. More information about 
         
     | 
| 
      
 23 
     | 
    
         
            +
            # yard and the rake task installed below can be found on http://yardoc.org/
         
     | 
| 
      
 24 
     | 
    
         
            +
            #
         
     | 
| 
      
 25 
     | 
    
         
            +
            begin
         
     | 
| 
      
 26 
     | 
    
         
            +
              require "yard"
         
     | 
| 
      
 27 
     | 
    
         
            +
              desc "Generate yard documentation"
         
     | 
| 
      
 28 
     | 
    
         
            +
              YARD::Rake::YardocTask.new(:yard) do |t|
         
     | 
| 
      
 29 
     | 
    
         
            +
                # Array of options passed to yardoc commandline. See 'yardoc --help' about this
         
     | 
| 
      
 30 
     | 
    
         
            +
                t.options = ["--output-dir", "doc/api", "-", "README.md", "CHANGELOG.md", "LICENCE.md"]
         
     | 
| 
      
 31 
     | 
    
         
            +
                
         
     | 
| 
      
 32 
     | 
    
         
            +
                # Array of ruby source files (and any extra documentation files 
         
     | 
| 
      
 33 
     | 
    
         
            +
                # separated by '-')
         
     | 
| 
      
 34 
     | 
    
         
            +
                t.files = ["lib/**/*.rb"]
         
     | 
| 
      
 35 
     | 
    
         
            +
                
         
     | 
| 
      
 36 
     | 
    
         
            +
                # A proc to call before running the task
         
     | 
| 
      
 37 
     | 
    
         
            +
                # t.before = proc{ }
         
     | 
| 
      
 38 
     | 
    
         
            +
                
         
     | 
| 
      
 39 
     | 
    
         
            +
                # A proc to call after running the task
         
     | 
| 
      
 40 
     | 
    
         
            +
                # r.after = proc{ }
         
     | 
| 
      
 41 
     | 
    
         
            +
                
         
     | 
| 
      
 42 
     | 
    
         
            +
                # An optional lambda to run against all objects being generated. 
         
     | 
| 
      
 43 
     | 
    
         
            +
                # Any object that the lambda returns false for will be excluded 
         
     | 
| 
      
 44 
     | 
    
         
            +
                # from documentation. 
         
     | 
| 
      
 45 
     | 
    
         
            +
                # t.verifier = lambda{|obj| true}
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 48 
     | 
    
         
            +
              task :yard do
         
     | 
| 
      
 49 
     | 
    
         
            +
                abort 'yard is not available. In order to run yard, you must: gem install yard'
         
     | 
| 
      
 50 
     | 
    
         
            +
              end
         
     | 
| 
      
 51 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,491 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test/unit'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'stamina'
         
     | 
| 
      
 3 
     | 
    
         
            +
            module Stamina
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              # Tests ADL parser
         
     | 
| 
      
 6 
     | 
    
         
            +
              class ADLTest < Test::Unit::TestCase
         
     | 
| 
      
 7 
     | 
    
         
            +
              
         
     | 
| 
      
 8 
     | 
    
         
            +
                # Tests ADL#parse on a valid dfa
         
     | 
| 
      
 9 
     | 
    
         
            +
                def test_can_parse_valid_empty_dfa
         
     | 
| 
      
 10 
     | 
    
         
            +
                  fa = ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 11 
     | 
    
         
            +
                    1 0
         
     | 
| 
      
 12 
     | 
    
         
            +
                    0 true false
         
     | 
| 
      
 13 
     | 
    
         
            +
                  AUTOMATON
         
     | 
| 
      
 14 
     | 
    
         
            +
                  assert_equal(1, fa.state_count)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  assert_equal(0, fa.edge_count)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  assert_equal(true, fa.states[0].initial?)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  assert_equal(false, fa.states[0].accepting?)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  assert_equal(true, fa.deterministic?)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('+'))
         
     | 
| 
      
 20 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('+ a'))
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              
         
     | 
| 
      
 23 
     | 
    
         
            +
                # Tests ADL#parse on a valid dfa
         
     | 
| 
      
 24 
     | 
    
         
            +
                def test_can_parse_valid_small_dfa
         
     | 
| 
      
 25 
     | 
    
         
            +
                  fa = ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 26 
     | 
    
         
            +
                    3 4
         
     | 
| 
      
 27 
     | 
    
         
            +
                    0 true false
         
     | 
| 
      
 28 
     | 
    
         
            +
                    1 false false
         
     | 
| 
      
 29 
     | 
    
         
            +
                    2 false true
         
     | 
| 
      
 30 
     | 
    
         
            +
                    0 1 a
         
     | 
| 
      
 31 
     | 
    
         
            +
                    1 2 b
         
     | 
| 
      
 32 
     | 
    
         
            +
                    2 2 a
         
     | 
| 
      
 33 
     | 
    
         
            +
                    2 1 b
         
     | 
| 
      
 34 
     | 
    
         
            +
                  AUTOMATON
         
     | 
| 
      
 35 
     | 
    
         
            +
                  assert_equal(3, fa.state_count)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  assert_equal(4, fa.edge_count)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  fa.each_state {|s| assert_equal(s.index==0, s.initial?)}
         
     | 
| 
      
 38 
     | 
    
         
            +
                  fa.each_state {|s| assert_equal(s.index==2, s.accepting?)}
         
     | 
| 
      
 39 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('+'))
         
     | 
| 
      
 40 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('+ a'))
         
     | 
| 
      
 41 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b'))
         
     | 
| 
      
 42 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a'))
         
     | 
| 
      
 43 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('+ a b a b'))
         
     | 
| 
      
 44 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a a a'))
         
     | 
| 
      
 45 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a a a b b a'))
         
     | 
| 
      
 46 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a a a b b a a a'))
         
     | 
| 
      
 47 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a a a b b a a a b b a'))
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              
         
     | 
| 
      
 50 
     | 
    
         
            +
                # Tests that ADL#parse detects a missing state
         
     | 
| 
      
 51 
     | 
    
         
            +
                def test_detect_missing_header
         
     | 
| 
      
 52 
     | 
    
         
            +
                  assert_raise(ADL::ParseError) do
         
     | 
| 
      
 53 
     | 
    
         
            +
                    ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 54 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 55 
     | 
    
         
            +
                      1 false false
         
     | 
| 
      
 56 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 57 
     | 
    
         
            +
                      1 2 b
         
     | 
| 
      
 58 
     | 
    
         
            +
                      2 2 a
         
     | 
| 
      
 59 
     | 
    
         
            +
                      2 1 b
         
     | 
| 
      
 60 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                  assert_raise(ADL::ParseError) do
         
     | 
| 
      
 63 
     | 
    
         
            +
                    ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 64 
     | 
    
         
            +
                      # 3 4
         
     | 
| 
      
 65 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 66 
     | 
    
         
            +
                      1 false false
         
     | 
| 
      
 67 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 68 
     | 
    
         
            +
                      1 2 b
         
     | 
| 
      
 69 
     | 
    
         
            +
                      2 2 a
         
     | 
| 
      
 70 
     | 
    
         
            +
                      2 1 b
         
     | 
| 
      
 71 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
              
         
     | 
| 
      
 75 
     | 
    
         
            +
                # Tests that ADL#parse detects a missing state
         
     | 
| 
      
 76 
     | 
    
         
            +
                def test_detect_missing_state
         
     | 
| 
      
 77 
     | 
    
         
            +
                  assert_raise(ADL::ParseError) do
         
     | 
| 
      
 78 
     | 
    
         
            +
                    ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 79 
     | 
    
         
            +
                      3 4
         
     | 
| 
      
 80 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 81 
     | 
    
         
            +
                      1 false false
         
     | 
| 
      
 82 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                  assert_raise(ADL::ParseError) do
         
     | 
| 
      
 85 
     | 
    
         
            +
                    ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 86 
     | 
    
         
            +
                      3 4
         
     | 
| 
      
 87 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 88 
     | 
    
         
            +
                      1 false false
         
     | 
| 
      
 89 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 90 
     | 
    
         
            +
                      1 2 b
         
     | 
| 
      
 91 
     | 
    
         
            +
                      2 2 a
         
     | 
| 
      
 92 
     | 
    
         
            +
                      2 1 b
         
     | 
| 
      
 93 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 94 
     | 
    
         
            +
                  end
         
     | 
| 
      
 95 
     | 
    
         
            +
                  assert_raise(ADL::ParseError) do
         
     | 
| 
      
 96 
     | 
    
         
            +
                    ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 97 
     | 
    
         
            +
                      3 4
         
     | 
| 
      
 98 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 99 
     | 
    
         
            +
                      1 false false
         
     | 
| 
      
 100 
     | 
    
         
            +
                      # 2 false true
         
     | 
| 
      
 101 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 102 
     | 
    
         
            +
                      1 2 b
         
     | 
| 
      
 103 
     | 
    
         
            +
                      2 2 a
         
     | 
| 
      
 104 
     | 
    
         
            +
                      2 1 b
         
     | 
| 
      
 105 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
                end
         
     | 
| 
      
 108 
     | 
    
         
            +
              
         
     | 
| 
      
 109 
     | 
    
         
            +
                # Tests that ADL#parse detects a missing edge
         
     | 
| 
      
 110 
     | 
    
         
            +
                def test_detect_missing_edge
         
     | 
| 
      
 111 
     | 
    
         
            +
                  assert_raise(ADL::ParseError) do
         
     | 
| 
      
 112 
     | 
    
         
            +
                    ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 113 
     | 
    
         
            +
                      3 4
         
     | 
| 
      
 114 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 115 
     | 
    
         
            +
                      1 false false
         
     | 
| 
      
 116 
     | 
    
         
            +
                      2 false true
         
     | 
| 
      
 117 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 118 
     | 
    
         
            +
                      2 2 a
         
     | 
| 
      
 119 
     | 
    
         
            +
                      2 1 b
         
     | 
| 
      
 120 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 121 
     | 
    
         
            +
                  end
         
     | 
| 
      
 122 
     | 
    
         
            +
                  assert_raise(ADL::ParseError) do
         
     | 
| 
      
 123 
     | 
    
         
            +
                    ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 124 
     | 
    
         
            +
                      3 4
         
     | 
| 
      
 125 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 126 
     | 
    
         
            +
                      1 false false
         
     | 
| 
      
 127 
     | 
    
         
            +
                      2 false true
         
     | 
| 
      
 128 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 129 
     | 
    
         
            +
                      1 2 b
         
     | 
| 
      
 130 
     | 
    
         
            +
                      2 2 a
         
     | 
| 
      
 131 
     | 
    
         
            +
                      # 2 1 b
         
     | 
| 
      
 132 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 133 
     | 
    
         
            +
                  end
         
     | 
| 
      
 134 
     | 
    
         
            +
                end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                # Tests that ADL#parse detects a missing edge
         
     | 
| 
      
 137 
     | 
    
         
            +
                def test_detect_trailing_data
         
     | 
| 
      
 138 
     | 
    
         
            +
                  assert_raise(ADL::ParseError) do
         
     | 
| 
      
 139 
     | 
    
         
            +
                    fa = ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 140 
     | 
    
         
            +
                      1 0
         
     | 
| 
      
 141 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 142 
     | 
    
         
            +
                      trailing here
         
     | 
| 
      
 143 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
              
         
     | 
| 
      
 147 
     | 
    
         
            +
                # Tests that ADL#parse detects a missing edge
         
     | 
| 
      
 148 
     | 
    
         
            +
                def test_allows_comments_and_white_lines
         
     | 
| 
      
 149 
     | 
    
         
            +
                  fa = nil
         
     | 
| 
      
 150 
     | 
    
         
            +
                  assert_nothing_raised(ADL::ParseError) do
         
     | 
| 
      
 151 
     | 
    
         
            +
                    fa = ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 152 
     | 
    
         
            +
                  
         
     | 
| 
      
 153 
     | 
    
         
            +
                      # a header is always allowed,
         
     | 
| 
      
 154 
     | 
    
         
            +
                      # with empty lines as well
         
     | 
| 
      
 155 
     | 
    
         
            +
                      #
         
     | 
| 
      
 156 
     | 
    
         
            +
                      3 4
         
     | 
| 
      
 157 
     | 
    
         
            +
                    
         
     | 
| 
      
 158 
     | 
    
         
            +
                      # state definitions may be introduced...
         
     | 
| 
      
 159 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 160 
     | 
    
         
            +
                      1 false false
         
     | 
| 
      
 161 
     | 
    
         
            +
                      # and perturbated
         
     | 
| 
      
 162 
     | 
    
         
            +
                      2 false true
         
     | 
| 
      
 163 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 164 
     | 
    
         
            +
                    
         
     | 
| 
      
 165 
     | 
    
         
            +
                      # edge introduction may be misplaced
         
     | 
| 
      
 166 
     | 
    
         
            +
                      1 2 b
         
     | 
| 
      
 167 
     | 
    
         
            +
                      2 2 a
         
     | 
| 
      
 168 
     | 
    
         
            +
                    
         
     | 
| 
      
 169 
     | 
    
         
            +
                      2 1 b
         
     | 
| 
      
 170 
     | 
    
         
            +
                    
         
     | 
| 
      
 171 
     | 
    
         
            +
                      # and end of file may contain documentation as well
         
     | 
| 
      
 172 
     | 
    
         
            +
                      # as empty lines:
         
     | 
| 
      
 173 
     | 
    
         
            +
                    
         
     | 
| 
      
 174 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 175 
     | 
    
         
            +
                  end
         
     | 
| 
      
 176 
     | 
    
         
            +
                  assert_equal(3, fa.state_count)
         
     | 
| 
      
 177 
     | 
    
         
            +
                  assert_equal(4, fa.edge_count)
         
     | 
| 
      
 178 
     | 
    
         
            +
                  fa.each_state {|s| assert_equal(s.index==0, s.initial?)}
         
     | 
| 
      
 179 
     | 
    
         
            +
                  fa.each_state {|s| assert_equal(s.index==2, s.accepting?)}
         
     | 
| 
      
 180 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('+'))
         
     | 
| 
      
 181 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('+ a'))
         
     | 
| 
      
 182 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b'))
         
     | 
| 
      
 183 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a'))
         
     | 
| 
      
 184 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('+ a b a b'))
         
     | 
| 
      
 185 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a a a'))
         
     | 
| 
      
 186 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a a a b b a'))
         
     | 
| 
      
 187 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a a a b b a a a'))
         
     | 
| 
      
 188 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('+ a b a a a b b a a a b b a'))
         
     | 
| 
      
 189 
     | 
    
         
            +
                end
         
     | 
| 
      
 190 
     | 
    
         
            +
              
         
     | 
| 
      
 191 
     | 
    
         
            +
                # Tests ADL::parse on the documentation example
         
     | 
| 
      
 192 
     | 
    
         
            +
                def test_valid_adl_automaton_example
         
     | 
| 
      
 193 
     | 
    
         
            +
                  fa = nil
         
     | 
| 
      
 194 
     | 
    
         
            +
                  assert_nothing_raised(ADL::ParseError) do
         
     | 
| 
      
 195 
     | 
    
         
            +
                    here =  File.dirname(__FILE__)
         
     | 
| 
      
 196 
     | 
    
         
            +
                    automaton_adl = File.join(here, '..', '..', 'example', 'adl', 'automaton.adl')
         
     | 
| 
      
 197 
     | 
    
         
            +
                    fa = ADL::parse_automaton_file(automaton_adl)
         
     | 
| 
      
 198 
     | 
    
         
            +
                  end # assert_nothing_raised
         
     | 
| 
      
 199 
     | 
    
         
            +
                  assert_equal(5, fa.state_count)
         
     | 
| 
      
 200 
     | 
    
         
            +
                  assert_equal(6, fa.edge_count)
         
     | 
| 
      
 201 
     | 
    
         
            +
                  assert_equal(true, fa.parses?('? hello w o r l d'))
         
     | 
| 
      
 202 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('? hello w o r l d'))
         
     | 
| 
      
 203 
     | 
    
         
            +
                  assert_equal(true, fa.rejects?('? hello w o r l d'))
         
     | 
| 
      
 204 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('? hello'))
         
     | 
| 
      
 205 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('? hello w'))
         
     | 
| 
      
 206 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('? hello w o'))
         
     | 
| 
      
 207 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('? hello w o r'))
         
     | 
| 
      
 208 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('? hello w o r l'))
         
     | 
| 
      
 209 
     | 
    
         
            +
                end
         
     | 
| 
      
 210 
     | 
    
         
            +
              
         
     | 
| 
      
 211 
     | 
    
         
            +
                # Tests ADL::parse on the documentation succint example
         
     | 
| 
      
 212 
     | 
    
         
            +
                def test_valid_adl_automaton_succint_example
         
     | 
| 
      
 213 
     | 
    
         
            +
                  fa = nil
         
     | 
| 
      
 214 
     | 
    
         
            +
                  assert_nothing_raised do
         
     | 
| 
      
 215 
     | 
    
         
            +
                    fa = ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 216 
     | 
    
         
            +
                      # Some header comments: tool which has generated this automaton,
         
     | 
| 
      
 217 
     | 
    
         
            +
                      # maybe a date or other tool options ...
         
     | 
| 
      
 218 
     | 
    
         
            +
                      # here: 'this automaton accepts the a(ba)* regular language'
         
     | 
| 
      
 219 
     | 
    
         
            +
                      2 2
         
     | 
| 
      
 220 
     | 
    
         
            +
                      0 true false
         
     | 
| 
      
 221 
     | 
    
         
            +
                      1 false true
         
     | 
| 
      
 222 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 223 
     | 
    
         
            +
                      1 0 b
         
     | 
| 
      
 224 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 225 
     | 
    
         
            +
                  end
         
     | 
| 
      
 226 
     | 
    
         
            +
                  assert_equal(2, fa.state_count)
         
     | 
| 
      
 227 
     | 
    
         
            +
                  assert_equal(2, fa.edge_count)
         
     | 
| 
      
 228 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('? a'))
         
     | 
| 
      
 229 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('? a b a'))
         
     | 
| 
      
 230 
     | 
    
         
            +
                  assert_equal(true, fa.accepts?('? a b a b a'))
         
     | 
| 
      
 231 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('?'))
         
     | 
| 
      
 232 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('? a b'))
         
     | 
| 
      
 233 
     | 
    
         
            +
                  assert_equal(false, fa.accepts?('? a b a b'))
         
     | 
| 
      
 234 
     | 
    
         
            +
                end
         
     | 
| 
      
 235 
     | 
    
         
            +
              
         
     | 
| 
      
 236 
     | 
    
         
            +
                # Checks that an initial state may arruve lately
         
     | 
| 
      
 237 
     | 
    
         
            +
                def test_parse_automaton_allows_late_initial_state
         
     | 
| 
      
 238 
     | 
    
         
            +
                  fa = nil
         
     | 
| 
      
 239 
     | 
    
         
            +
                  assert_nothing_raised do
         
     | 
| 
      
 240 
     | 
    
         
            +
                    fa = ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 241 
     | 
    
         
            +
                      # Some header comments: tool which has generated this automaton,
         
     | 
| 
      
 242 
     | 
    
         
            +
                      # maybe a date or other tool options ...
         
     | 
| 
      
 243 
     | 
    
         
            +
                      # here: 'this automaton accepts the a(ba)* regular language'
         
     | 
| 
      
 244 
     | 
    
         
            +
                      2 2
         
     | 
| 
      
 245 
     | 
    
         
            +
                      0 false false
         
     | 
| 
      
 246 
     | 
    
         
            +
                      1 true true
         
     | 
| 
      
 247 
     | 
    
         
            +
                      0 1 a
         
     | 
| 
      
 248 
     | 
    
         
            +
                      1 0 b
         
     | 
| 
      
 249 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 250 
     | 
    
         
            +
                  end
         
     | 
| 
      
 251 
     | 
    
         
            +
                end
         
     | 
| 
      
 252 
     | 
    
         
            +
              
         
     | 
| 
      
 253 
     | 
    
         
            +
                # Tests parse_automaton on an automated randomly generated using jail
         
     | 
| 
      
 254 
     | 
    
         
            +
                def test_parse_automaton_on_jail_randdfa
         
     | 
| 
      
 255 
     | 
    
         
            +
                  fa = nil
         
     | 
| 
      
 256 
     | 
    
         
            +
                  assert_nothing_raised do
         
     | 
| 
      
 257 
     | 
    
         
            +
                    fa = ADL::parse_automaton_file(File.join(File.dirname(__FILE__),'randdfa.adl'))
         
     | 
| 
      
 258 
     | 
    
         
            +
                  end
         
     | 
| 
      
 259 
     | 
    
         
            +
                end
         
     | 
| 
      
 260 
     | 
    
         
            +
              
         
     | 
| 
      
 261 
     | 
    
         
            +
                # Tests an important security issue about parse_automaton
         
     | 
| 
      
 262 
     | 
    
         
            +
                def test_parse_automaton_does_not_executes_ruby_code
         
     | 
| 
      
 263 
     | 
    
         
            +
                  begin 
         
     | 
| 
      
 264 
     | 
    
         
            +
                    assert_raise ADL::ParseError do
         
     | 
| 
      
 265 
     | 
    
         
            +
                      ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 266 
     | 
    
         
            +
                      Kernel.exit(-1)
         
     | 
| 
      
 267 
     | 
    
         
            +
                      AUTOMATON
         
     | 
| 
      
 268 
     | 
    
         
            +
                    end
         
     | 
| 
      
 269 
     | 
    
         
            +
                  rescue SystemExit
         
     | 
| 
      
 270 
     | 
    
         
            +
                    assert false, 'SECURITY issue: ADL::parse_automaton executes ruby code'
         
     | 
| 
      
 271 
     | 
    
         
            +
                  end
         
     | 
| 
      
 272 
     | 
    
         
            +
                  begin 
         
     | 
| 
      
 273 
     | 
    
         
            +
                    assert_raise ADL::ParseError do
         
     | 
| 
      
 274 
     | 
    
         
            +
                      ADL::parse_automaton_file(File.dirname(__FILE__)+'/exit.rb') 
         
     | 
| 
      
 275 
     | 
    
         
            +
                    end
         
     | 
| 
      
 276 
     | 
    
         
            +
                  rescue SystemExit
         
     | 
| 
      
 277 
     | 
    
         
            +
                    assert false, 'SECURITY issue: ADL::parse_automaton executes ruby code'
         
     | 
| 
      
 278 
     | 
    
         
            +
                  end
         
     | 
| 
      
 279 
     | 
    
         
            +
                end
         
     | 
| 
      
 280 
     | 
    
         
            +
              
         
     | 
| 
      
 281 
     | 
    
         
            +
                # Tests ADL::parse_string
         
     | 
| 
      
 282 
     | 
    
         
            +
                def test_parse_string
         
     | 
| 
      
 283 
     | 
    
         
            +
                  s = ADL::parse_string('?')
         
     | 
| 
      
 284 
     | 
    
         
            +
                  assert_equal(true, InputString===s)
         
     | 
| 
      
 285 
     | 
    
         
            +
                  assert_equal(false, s.positive?)
         
     | 
| 
      
 286 
     | 
    
         
            +
                  assert_equal(false, s.negative?)
         
     | 
| 
      
 287 
     | 
    
         
            +
                  assert_equal(true, s.unlabeled?)
         
     | 
| 
      
 288 
     | 
    
         
            +
                  assert_equal(nil, s.label)
         
     | 
| 
      
 289 
     | 
    
         
            +
                  assert_equal(true, s.empty?)
         
     | 
| 
      
 290 
     | 
    
         
            +
                  assert_equal([], s.symbols)
         
     | 
| 
      
 291 
     | 
    
         
            +
             
     | 
| 
      
 292 
     | 
    
         
            +
                  s = ADL::parse_string('+')
         
     | 
| 
      
 293 
     | 
    
         
            +
                  assert_equal(true, InputString===s)
         
     | 
| 
      
 294 
     | 
    
         
            +
                  assert_equal(true, s.positive?)
         
     | 
| 
      
 295 
     | 
    
         
            +
                  assert_equal(true, s.label)
         
     | 
| 
      
 296 
     | 
    
         
            +
                  assert_equal(true, s.empty?)
         
     | 
| 
      
 297 
     | 
    
         
            +
                  assert_equal([], s.symbols)
         
     | 
| 
      
 298 
     | 
    
         
            +
                
         
     | 
| 
      
 299 
     | 
    
         
            +
                  s = ADL::parse_string('-')
         
     | 
| 
      
 300 
     | 
    
         
            +
                  assert_equal(true, InputString===s)
         
     | 
| 
      
 301 
     | 
    
         
            +
                  assert_equal(false, s.positive?)
         
     | 
| 
      
 302 
     | 
    
         
            +
                  assert_equal(false, s.label)
         
     | 
| 
      
 303 
     | 
    
         
            +
                  assert_equal(true, s.empty?)
         
     | 
| 
      
 304 
     | 
    
         
            +
                  assert_equal([], s.symbols)
         
     | 
| 
      
 305 
     | 
    
         
            +
                
         
     | 
| 
      
 306 
     | 
    
         
            +
                  s = ADL::parse_string('? a')
         
     | 
| 
      
 307 
     | 
    
         
            +
                  assert_equal(['a'], s.symbols)
         
     | 
| 
      
 308 
     | 
    
         
            +
                  assert_equal(false, s.positive?)
         
     | 
| 
      
 309 
     | 
    
         
            +
                  assert_equal(false, s.negative?)
         
     | 
| 
      
 310 
     | 
    
         
            +
                  assert_equal(true, s.unlabeled?)
         
     | 
| 
      
 311 
     | 
    
         
            +
                  assert_equal(nil, s.label)
         
     | 
| 
      
 312 
     | 
    
         
            +
                  assert_equal(['a'], s.symbols)
         
     | 
| 
      
 313 
     | 
    
         
            +
                
         
     | 
| 
      
 314 
     | 
    
         
            +
                  s = ADL::parse_string('+ a')
         
     | 
| 
      
 315 
     | 
    
         
            +
                  assert_equal(['a'], s.symbols)
         
     | 
| 
      
 316 
     | 
    
         
            +
                  assert_equal(true, s.positive?)
         
     | 
| 
      
 317 
     | 
    
         
            +
                
         
     | 
| 
      
 318 
     | 
    
         
            +
                  s = ADL::parse_string('- a')
         
     | 
| 
      
 319 
     | 
    
         
            +
                  assert_equal(['a'], s.symbols)
         
     | 
| 
      
 320 
     | 
    
         
            +
                  assert_equal(false, s.positive?)
         
     | 
| 
      
 321 
     | 
    
         
            +
                
         
     | 
| 
      
 322 
     | 
    
         
            +
                  s = ADL::parse_string('+ a b a b ')
         
     | 
| 
      
 323 
     | 
    
         
            +
                  assert_equal(['a','b','a','b'], s.symbols)
         
     | 
| 
      
 324 
     | 
    
         
            +
                  assert_equal(true, s.positive?)
         
     | 
| 
      
 325 
     | 
    
         
            +
                
         
     | 
| 
      
 326 
     | 
    
         
            +
                  s = ADL::parse_string('- a b a c')
         
     | 
| 
      
 327 
     | 
    
         
            +
                  assert_equal(['a','b','a','c'], s.symbols)
         
     | 
| 
      
 328 
     | 
    
         
            +
                  assert_equal(false, s.positive?)
         
     | 
| 
      
 329 
     | 
    
         
            +
                end
         
     | 
| 
      
 330 
     | 
    
         
            +
              
         
     | 
| 
      
 331 
     | 
    
         
            +
                # Tests ADL::parse_sample
         
     | 
| 
      
 332 
     | 
    
         
            +
                def test_parse_sample
         
     | 
| 
      
 333 
     | 
    
         
            +
                  sample = ADL::parse_sample <<-SAMPLE
         
     | 
| 
      
 334 
     | 
    
         
            +
                  + a b  a b  a b
         
     | 
| 
      
 335 
     | 
    
         
            +
                  # this is a comment, next is an empty line
         
     | 
| 
      
 336 
     | 
    
         
            +
                  +
         
     | 
| 
      
 337 
     | 
    
         
            +
                  + a   b
         
     | 
| 
      
 338 
     | 
    
         
            +
                  - a a
         
     | 
| 
      
 339 
     | 
    
         
            +
                  ? a b
         
     | 
| 
      
 340 
     | 
    
         
            +
                  # trailing comment allowed
         
     | 
| 
      
 341 
     | 
    
         
            +
                  SAMPLE
         
     | 
| 
      
 342 
     | 
    
         
            +
                  assert sample==Sample['+ a b a b a b', '+ a b', '- a a', '+', '? a b']
         
     | 
| 
      
 343 
     | 
    
         
            +
                end
         
     | 
| 
      
 344 
     | 
    
         
            +
              
         
     | 
| 
      
 345 
     | 
    
         
            +
                # Tests that ADL::parse_sample accepts the empty sample
         
     | 
| 
      
 346 
     | 
    
         
            +
                def test_parse_sample_accepts_empty_sample
         
     | 
| 
      
 347 
     | 
    
         
            +
                  samples = [
         
     | 
| 
      
 348 
     | 
    
         
            +
                    ADL::parse_sample(""),
         
     | 
| 
      
 349 
     | 
    
         
            +
                    ADL::parse_sample("#"),
         
     | 
| 
      
 350 
     | 
    
         
            +
                    ADL::parse_sample(<<-SAMPLE 
         
     | 
| 
      
 351 
     | 
    
         
            +
                    SAMPLE
         
     | 
| 
      
 352 
     | 
    
         
            +
                    ),
         
     | 
| 
      
 353 
     | 
    
         
            +
                    ADL::parse_sample(<<-SAMPLE
         
     | 
| 
      
 354 
     | 
    
         
            +
                    
         
     | 
| 
      
 355 
     | 
    
         
            +
                      # this is a comment, between two empty lines
         
     | 
| 
      
 356 
     | 
    
         
            +
                  
         
     | 
| 
      
 357 
     | 
    
         
            +
                    SAMPLE
         
     | 
| 
      
 358 
     | 
    
         
            +
                    )
         
     | 
| 
      
 359 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 360 
     | 
    
         
            +
                  samples.each do |sample|
         
     | 
| 
      
 361 
     | 
    
         
            +
                    assert sample==Sample.new
         
     | 
| 
      
 362 
     | 
    
         
            +
                  end
         
     | 
| 
      
 363 
     | 
    
         
            +
                end
         
     | 
| 
      
 364 
     | 
    
         
            +
              
         
     | 
| 
      
 365 
     | 
    
         
            +
                # Tests that ADL::parse_sample accepts empty strings
         
     | 
| 
      
 366 
     | 
    
         
            +
                def test_parse_sample_accepts_empty_strings
         
     | 
| 
      
 367 
     | 
    
         
            +
                  assert Sample['+'] == ADL::parse_sample('+')
         
     | 
| 
      
 368 
     | 
    
         
            +
                  assert Sample['-'] == ADL::parse_sample('-')
         
     | 
| 
      
 369 
     | 
    
         
            +
                  assert Sample['+'] == ADL::parse_sample(<<-SAMPLE
         
     | 
| 
      
 370 
     | 
    
         
            +
                    +
         
     | 
| 
      
 371 
     | 
    
         
            +
                  SAMPLE
         
     | 
| 
      
 372 
     | 
    
         
            +
                  )
         
     | 
| 
      
 373 
     | 
    
         
            +
                  assert Sample['-'] == ADL::parse_sample(<<-SAMPLE
         
     | 
| 
      
 374 
     | 
    
         
            +
                    -
         
     | 
| 
      
 375 
     | 
    
         
            +
                  SAMPLE
         
     | 
| 
      
 376 
     | 
    
         
            +
                  )
         
     | 
| 
      
 377 
     | 
    
         
            +
                end  
         
     | 
| 
      
 378 
     | 
    
         
            +
              
         
     | 
| 
      
 379 
     | 
    
         
            +
                # Tests validity of sample.adl file
         
     | 
| 
      
 380 
     | 
    
         
            +
                def test_valid_adl_sample_example
         
     | 
| 
      
 381 
     | 
    
         
            +
                  here =  File.dirname(__FILE__)
         
     | 
| 
      
 382 
     | 
    
         
            +
                  sample_adl = File.join(here, '..', '..', 'example', 'adl', 'sample.adl')
         
     | 
| 
      
 383 
     | 
    
         
            +
                  sample = ADL::parse_sample_file(sample_adl)
         
     | 
| 
      
 384 
     | 
    
         
            +
                  expected = Sample.new 
         
     | 
| 
      
 385 
     | 
    
         
            +
                  expected << InputString.new(['a', 'b', 'a', 'b'], true)
         
     | 
| 
      
 386 
     | 
    
         
            +
                  expected << InputString.new(['a', 'a'], false)
         
     | 
| 
      
 387 
     | 
    
         
            +
                  expected << InputString.new(['a', 'b'], nil)
         
     | 
| 
      
 388 
     | 
    
         
            +
                  expected << InputString.new([], true)
         
     | 
| 
      
 389 
     | 
    
         
            +
                  expected << InputString.new(['hello', 'world'], true)
         
     | 
| 
      
 390 
     | 
    
         
            +
                  expected << InputString.new(['h','e','l','l','o','w','o','r','l','d'], true)
         
     | 
| 
      
 391 
     | 
    
         
            +
                  expected << InputString.new(['helloworld'], true)
         
     | 
| 
      
 392 
     | 
    
         
            +
                  expected << InputString.new(['a','+','b','-','a','-','b','+a'], true)
         
     | 
| 
      
 393 
     | 
    
         
            +
                  expected << InputString.new(['#','a','#','b','a','b','#','and','all','these','words','are','symbols', 'too', '!!'],true)
         
     | 
| 
      
 394 
     | 
    
         
            +
                  expected.each do |s|
         
     | 
| 
      
 395 
     | 
    
         
            +
                    assert sample.include?(s), "|#{s}| from expected is included in sample"
         
     | 
| 
      
 396 
     | 
    
         
            +
                  end
         
     | 
| 
      
 397 
     | 
    
         
            +
                  sample.each do |s|
         
     | 
| 
      
 398 
     | 
    
         
            +
                    assert expected.include?(s), "|#{s}| from sample is included in expected"
         
     | 
| 
      
 399 
     | 
    
         
            +
                  end
         
     | 
| 
      
 400 
     | 
    
         
            +
                  assert expected == sample
         
     | 
| 
      
 401 
     | 
    
         
            +
                end
         
     | 
| 
      
 402 
     | 
    
         
            +
             
     | 
| 
      
 403 
     | 
    
         
            +
                # Tests validity of sample.adl file
         
     | 
| 
      
 404 
     | 
    
         
            +
                def test_valid_adl_sample_succint_example
         
     | 
| 
      
 405 
     | 
    
         
            +
                  sample = ADL::parse_sample <<-SAMPLE
         
     | 
| 
      
 406 
     | 
    
         
            +
                    # Some header comments: tool which has generated this sample,
         
     | 
| 
      
 407 
     | 
    
         
            +
                    # maybe a date or other tool options ...
         
     | 
| 
      
 408 
     | 
    
         
            +
                    # here: 'this sample is caracteristic for the a(ba)* regular language'
         
     | 
| 
      
 409 
     | 
    
         
            +
                    -
         
     | 
| 
      
 410 
     | 
    
         
            +
                    + a
         
     | 
| 
      
 411 
     | 
    
         
            +
                    - a b
         
     | 
| 
      
 412 
     | 
    
         
            +
                    + a b a
         
     | 
| 
      
 413 
     | 
    
         
            +
                  SAMPLE
         
     | 
| 
      
 414 
     | 
    
         
            +
                  expected = Sample.new
         
     | 
| 
      
 415 
     | 
    
         
            +
                  expected << InputString.new([], false)
         
     | 
| 
      
 416 
     | 
    
         
            +
                  expected << InputString.new(['a'], true)
         
     | 
| 
      
 417 
     | 
    
         
            +
                  expected << InputString.new(['a','b'], false)
         
     | 
| 
      
 418 
     | 
    
         
            +
                  expected << InputString.new(['a','b','a'], true)
         
     | 
| 
      
 419 
     | 
    
         
            +
                  assert expected==sample
         
     | 
| 
      
 420 
     | 
    
         
            +
                end  
         
     | 
| 
      
 421 
     | 
    
         
            +
              
         
     | 
| 
      
 422 
     | 
    
         
            +
                # Tests an important security issue about parse_automaton
         
     | 
| 
      
 423 
     | 
    
         
            +
                def test_parse_sample_does_not_executes_ruby_code
         
     | 
| 
      
 424 
     | 
    
         
            +
                  begin 
         
     | 
| 
      
 425 
     | 
    
         
            +
                    ADL::parse_sample <<-AUTOMATON
         
     | 
| 
      
 426 
     | 
    
         
            +
                    + Kernel.exit(-1)
         
     | 
| 
      
 427 
     | 
    
         
            +
                    AUTOMATON
         
     | 
| 
      
 428 
     | 
    
         
            +
                  rescue SystemExit
         
     | 
| 
      
 429 
     | 
    
         
            +
                    assert false, 'SECURITY issue: ADL::parse_automaton executes ruby code'
         
     | 
| 
      
 430 
     | 
    
         
            +
                  end
         
     | 
| 
      
 431 
     | 
    
         
            +
                  begin 
         
     | 
| 
      
 432 
     | 
    
         
            +
                    ADL::parse_sample_file(File.dirname(__FILE__)+'/exit.rb') 
         
     | 
| 
      
 433 
     | 
    
         
            +
                  rescue SystemExit
         
     | 
| 
      
 434 
     | 
    
         
            +
                    assert false, 'SECURITY issue: ADL::parse_automaton executes ruby code'
         
     | 
| 
      
 435 
     | 
    
         
            +
                  end
         
     | 
| 
      
 436 
     | 
    
         
            +
                end
         
     | 
| 
      
 437 
     | 
    
         
            +
             
     | 
| 
      
 438 
     | 
    
         
            +
                # tests that state IDs are loaded and can be used.
         
     | 
| 
      
 439 
     | 
    
         
            +
                def test_state_names
         
     | 
| 
      
 440 
     | 
    
         
            +
                  fa = ADL::parse_automaton <<-AUTOMATON
         
     | 
| 
      
 441 
     | 
    
         
            +
                    3 4
         
     | 
| 
      
 442 
     | 
    
         
            +
                    A true false
         
     | 
| 
      
 443 
     | 
    
         
            +
                    B false false
         
     | 
| 
      
 444 
     | 
    
         
            +
                    C false true
         
     | 
| 
      
 445 
     | 
    
         
            +
                    A B a
         
     | 
| 
      
 446 
     | 
    
         
            +
                    B C b
         
     | 
| 
      
 447 
     | 
    
         
            +
                    C C a
         
     | 
| 
      
 448 
     | 
    
         
            +
                    C B b
         
     | 
| 
      
 449 
     | 
    
         
            +
                  AUTOMATON
         
     | 
| 
      
 450 
     | 
    
         
            +
             
     | 
| 
      
 451 
     | 
    
         
            +
                  ['A','B','C'].each do |statename|
         
     | 
| 
      
 452 
     | 
    
         
            +
                    assert_equal statename,fa.get_state(statename)[:name]
         
     | 
| 
      
 453 
     | 
    
         
            +
                  end
         
     | 
| 
      
 454 
     | 
    
         
            +
             
     | 
| 
      
 455 
     | 
    
         
            +
                  assert_equal true,fa.get_state('A').initial?
         
     | 
| 
      
 456 
     | 
    
         
            +
                  assert_equal false,fa.get_state('B').initial?
         
     | 
| 
      
 457 
     | 
    
         
            +
                  assert_equal false,fa.get_state('C').initial?
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
                  assert_equal false,fa.get_state('A').accepting?
         
     | 
| 
      
 460 
     | 
    
         
            +
                  assert_equal false,fa.get_state('B').accepting?
         
     | 
| 
      
 461 
     | 
    
         
            +
                  assert_equal true,fa.get_state('C').accepting?
         
     | 
| 
      
 462 
     | 
    
         
            +
                end
         
     | 
| 
      
 463 
     | 
    
         
            +
              
         
     | 
| 
      
 464 
     | 
    
         
            +
                def test_parsing_recognizes_failures
         
     | 
| 
      
 465 
     | 
    
         
            +
                  assert_raise Stamina::ADL::ParseError do 
         
     | 
| 
      
 466 
     | 
    
         
            +
                    fa = ADL::parse_sample <<-EOF
         
     | 
| 
      
 467 
     | 
    
         
            +
                      3 4
         
     | 
| 
      
 468 
     | 
    
         
            +
                      A true false
         
     | 
| 
      
 469 
     | 
    
         
            +
                      B false false
         
     | 
| 
      
 470 
     | 
    
         
            +
                      C false true
         
     | 
| 
      
 471 
     | 
    
         
            +
                      A B a
         
     | 
| 
      
 472 
     | 
    
         
            +
                      B C b
         
     | 
| 
      
 473 
     | 
    
         
            +
                      C C a
         
     | 
| 
      
 474 
     | 
    
         
            +
                      C B b
         
     | 
| 
      
 475 
     | 
    
         
            +
                    EOF
         
     | 
| 
      
 476 
     | 
    
         
            +
                  end
         
     | 
| 
      
 477 
     | 
    
         
            +
                  assert_raise Stamina::ADL::ParseError do 
         
     | 
| 
      
 478 
     | 
    
         
            +
                    sample = ADL::parse_automaton <<-EOF
         
     | 
| 
      
 479 
     | 
    
         
            +
                      + a b  a b  a b
         
     | 
| 
      
 480 
     | 
    
         
            +
                      # this is a comment, next is an empty line
         
     | 
| 
      
 481 
     | 
    
         
            +
                      +
         
     | 
| 
      
 482 
     | 
    
         
            +
                      + a   b
         
     | 
| 
      
 483 
     | 
    
         
            +
                      - a a
         
     | 
| 
      
 484 
     | 
    
         
            +
                      a b
         
     | 
| 
      
 485 
     | 
    
         
            +
                      # trailing comment allowed
         
     | 
| 
      
 486 
     | 
    
         
            +
                    EOF
         
     | 
| 
      
 487 
     | 
    
         
            +
                  end
         
     | 
| 
      
 488 
     | 
    
         
            +
                end
         
     | 
| 
      
 489 
     | 
    
         
            +
              end # class ADLTest
         
     | 
| 
      
 490 
     | 
    
         
            +
                
         
     | 
| 
      
 491 
     | 
    
         
            +
            end # module Stamina
         
     |