.. _wowool_reference_guide_testing_keywords: Testing keywords **************** The testing keywords are prefixed with a '@' sign. This allows you test your samples at compiling time, just by adding the --unit-test (or the short form -t) option and the language: **Command:** woc --unit-test -l english test.wow -o test.dom you can use the shorter versions as well: woc -t -l en test.wow -o test.dom @stem ===== Switch on or off the syntax checker to analyze the stems in the rules or lexicons. This will only be performed when using the "stem" or "normalized_stem" options in lexicons or the single quotes in the rules. But for some lexicons you might not want to check the stem. At that point you can switch the analyzer off or on at any point in the file. .. code-block:: console @stem:on lexicon:(input="stem") { children, freind, } = LovelyPeople; rule: {'reindeers' 'are' 'better' } = ReindeerLove; @stem:off lexicon:(input="stem") { covfefe } = TrumpWord; **Command:** .. code-block:: console woc --unit-test -l english test.wow -o test.dom **Output:** | INFO:Compiling: | warning:Lexicon entry has a wrong stem: children -> child , | Lexicon entry has a wrong stem: reindeers -> reindeer , | Lexicon entry has a wrong stem: are -> be , | warning:Lexicon entry has not been found, so it still will match: freind As you can see in the case the form is found in the dictionary, the compiler will return a message suggesting the right stem: `children` -> `child` If the form is not found, you will just get a warning. @test ===== Create a test for the next rule in the source code. If you do not specify the expected result then we assume the expected results to be the top level rule annotation. This would be the same as adding @expected *[text to test]* = *[uri]* @test:[text to test] .. code-block:: console @test: The quick brown fox rule: { (Det)? (Adj)* (Nn)+ } = NounPhrase; **Command:** .. code-block:: console woc --unit-test -l english test.wow -o test.dom **Output:** | INFO:TestResult: 1 rules, 1 tests, 0 failed In this case the rule has matched the test. .. note:: If the test sample is longer than the span of the rule you will get an error: .. code-block:: console @test: The quick brown fox jumped over the lazy fox rule: { (Det)? (Adj)* (Nn)+ } = NounPhrase; **Command:** .. code-block:: console woc --unit-test -l english test.wow -o test.dom **Output:** | ERROR: @expected[failed]: { The quick brown fox jumped over the lazy fox } = NounPhrase; | INFO:TestResult: 1 rules, 1 tests, 1 failed To solve this ,in case you do not want to lose the original sentence, you can use the following keyword @expected. @expected ========= With the expected statement you can specify the expected results, you will need this if you have a more complex rule. You can add more than one expected result. .. code-block:: console @test: The quick brown fox jumped over the lazy fox @expected: The quick brown fox @expected: the lazy fox rule: { (Det)? (Adj)* (Nn)+ } = NounPhrase; **Command:** .. code-block:: console woc --unit-test -l english test.wow -o test.dom **Output:** | INFO:TestResult: 1 rules, 1 tests, 0 failed If you have several annotations, you have to add the annotation it needs to match: .. code-block:: console @test: John Doe ate a bagel @expected: John Doe = Eater @expected: bagel = Food rule: { {(Prop)+}=Eater 'eat' (Det)? {Nn}=Food }; @not_expected ============== With the not_expected statement you can specify the uri that are not expected in the results. This is used when testing filter rules: .. code-block:: console @test: Mercedes Benz @expected: Mercedes Benz = wow::filter @not_expected: Person //------------------------------------ rule: { Person [ NoPerson ] } = wow::filter@(concept="/Person/"); @dependency =========== With the dependency statement you can specify annotations that are coming from other domains. @dependency:[text to test] = [uri] .. code-block:: console @test: John Doe works at EyeOnText @expected: John Doe = SM_Person @dependency: John Doe = Person @expected: EyeOnText = SM_Company @dependency: EyeOnText = Company @expected: John Doe works at EyeOnText = PersonWorking rule: { {Person} = SM_Person V .. { Company }=SM_Company } = PersonWorking; **Command** woc --unit-test -l english -o test.dom test.wow .. note:: You can also use the test keywords after comments to visually separate it from the rules: .. code-block:: console //------------------------------------------ // @test: The quick brown fox jumped over the lazy fox // @expected: The quick brown fox // @expected: the lazy fox //------------------------------------------ rule: { (Det)? (Adj)* (Nn)+ } = NounPhrase; @language ========= With the @language you can avoid running some tests which are supposed to be for another language. In this example we would compile the .wow file for `dutch` but this test is ment to capture english words. So by adding the language tag we will avoid running this given test when compiling a dutch domain. @language: [language] .. code-block:: console @test: National Resistance Front @expected: National Resistance Front = Organization @language: english rule: { (+init-cap)+ "Front" ("of" (+init-cap)+)? } = Organization; **Command** woc --unit-test -l dutch -o test.dom test.wow Testing ------- From version 2.0.1 we introduced inline testing capabilities, which means that you can test your rules while building them. This will help you develop and understand the rules you are writing. Let's see a sample. .. code-block:: console //------------------------------------ // @test: John Dow works at EyeOnText //------------------------------------ rule: { Person V .. Company } = PersonWorking; **Command:** .. code-block:: console woc --domain rules --dependencies english-entity --unit-test -l english --verbose trace .. note:: --domain rules : is the location of your rule files. --unit-test : to run the test. --dependencies english-entity : is the list of domains your domain depends on. In this case, the english entities, as we need Person and Company. -l english : to run the english language module on the given rules. troubleshooting. ---------------- In case the rule does not match we will return the expected rules that have failed and their location. In the given example, we have added an s to the expected results: *@expected: Dingeldongs= SM_Person*. The software will indicate the failing expected result (_@expected[failed]_) and print out the annotated input text in debug mode. (--verbose debug) .. code-block:: console test [/...rules/ssn.wow] -------------------------------------------------------- @test[failed]: bin/rules/ssn.wow:10: Mr. Dingeldong traveled to BlaBla Inc. @expected[failed]: { Dingeldongs } = SM_Person; @expected[ok]: { BlaBla } = SM_Company; @expected[ok]: { Dingeldong traveled to BlaBla } = PersonWorking; - - - - - - - - - - - - - - - - - - - - - - - - - - - bin/rules/ssn.wow:10: rule:{ { Person }= SM_Person V .. { Company }= SM_Company }= PersonWorking s(1,40) {Sentence {NP @ rule=english/syntax/NounPhrase.wow:487; t(1,4) "Mr." (init-cap, init-token, abbrev)['Mr.':Prop-Std, +title] {PersonWorking @ rule=bin/rules/ssn.wow:10; {SM_Person @ rule=bin/rules/ssn.wow:10; {Person @ rule=lxcommon/rules/person.wow:441; {PersonFam @ rule=lxcommon/rules/person.wow:441; t(5,15) "Dingeldong" (init-cap, NF, NF-Lex)['Dingeldong':Prop-Std] }PersonFam }Person }SM_Person }NP {VP @ negation=false; rule=english/syntax/VerbPhrase.wow:632; voice=active; t(17,25) "traveled" ['travel':V-Past] }VP t(26,28) "to" ['to':Prep-to] {NP @ rule=english/syntax/NounPhrase.wow:487; {SM_Company @ rule=bin/rules/ssn.wow:10; {Company @ rule=lxcommon/rules/company-conjecture.wow:12; rule=lxcommon/rules/company-conjecture.wow:45; t(29,35) "BlaBla" (NF, NF-Lex)['BlaBla':Prop-Std] }Company }SM_Company }PersonWorking t(36,40) "Inc." (init-cap, abbrev)['Inc.':Prop-Std] }NP }Sentence