# -*- tcl -*-
# finite_automaton.test:  tests for the grammar::fa container.
#
# Copyright (c) 2004-2007 by Andreas Kupries <andreas_kupries@users.sourceforge.net>
#
# RCS: @(#) $Id: fa_state.test,v 1.8 2009/10/27 21:17:23 andreas_kupries Exp $

# -------------------------------------------------------------------------

test fa-state-${setimpl}-1.0 {state, error} {
    grammar::fa a
    catch {a state} res
    a destroy
    set res
} {wrong number args: should be "::a state method args"}
# [tcltest::wrongNumArgs {::a state method} {args} 0]


test fa-state-${setimpl}-1.1 {state, error} {
    grammar::fa a
    catch {a state add} res
    a destroy
    set res
} [tcltest::wrongNumArgs ::grammar::fa::Snit_hmethodstate_add {type selfns win self s args} 4]


test fa-state-${setimpl}-1.2 {state, error} {
    grammar::fa a
    a state add x
    catch {a state foo x} res
    a destroy
    set res
} {"::a state foo" is not defined}


test fa-state-${setimpl}-1.3 {state, error} {
    grammar::fa a
    a state add x
    catch {a state add x} res
    a destroy
    set res
} {State "x" is already known}


test fa-state-${setimpl}-1.4 {state, error} {
    grammar::fa a
    catch {a state exists} res
    a destroy
    set res
} [tcltest::wrongNumArgs ::grammar::fa::Snit_hmethodstate_exists {type selfns win self s} 4]


test fa-state-${setimpl}-1.5 {state, error} {
    grammar::fa a
    catch {a state exists a b} res
    a destroy
    set res
} {wrong # args: should be "::grammar::fa::Snit_hmethodstate_exists type selfns win self s"}


test fa-state-${setimpl}-1.6 {state, error} {
    grammar::fa a
    catch {a state delete} res
    a destroy
    set res
} [tcltest::wrongNumArgs ::grammar::fa::Snit_hmethodstate_delete {type selfns win self s args} 4]


test fa-state-${setimpl}-1.7 {state, error} {
    grammar::fa a
    catch {a state delete x} res
    a destroy
    set res
} {Illegal state "x"}


test fa-state-${setimpl}-1.8 {state, error} {
    grammar::fa a
    catch {a state rename} res
    a destroy
    set res
} [tcltest::wrongNumArgs ::grammar::fa::Snit_hmethodstate_rename {type selfns win self s snew} 0]


test fa-state-${setimpl}-1.9 {state, error} {
    grammar::fa a
    catch {a state rename foo} res
    a destroy
    set res
} [tcltest::wrongNumArgs ::grammar::fa::Snit_hmethodstate_rename {type selfns win self s snew} 1]


test fa-state-${setimpl}-1.10 {state, error} {
    grammar::fa a
    catch {a state rename x y} res
    a destroy
    set res
} {Illegal state "x"}


test fa-state-${setimpl}-1.11 {state, error} {
    grammar::fa a
    a state add x y
    catch {a state rename x y} res
    a destroy
    set res
} {State "y" is already known}


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


test fa-state-${setimpl}-2.0 {state add} {
    grammar::fa a
    set res [a state add x]
    a destroy
    set res
} {}


test fa-state-${setimpl}-2.1 {state add, variadic} {
    grammar::fa a
    set res [a state add x y]
    a destroy
    set res
} {}


test fa-state-${setimpl}-2.2 {state add / states / exists} {
    grammar::fa a
    a state add x
    set     res [a states]
    lappend res [a state exists x]
    lappend res [a state exists y]
    a destroy
    set res
} {x 1 0}


test fa-state-${setimpl}-2.3 {state add / states / exists} {
    grammar::fa a
    a state add x y
    set res {}
    lappend res [lsort [a states]]
    lappend res [a state exists x]
    lappend res [a state exists y]
    a destroy
    set res
} {{x y} 1 1}


test fa-state-${setimpl}-2.4 {state add, basic properties} {
    grammar::fa a
    a state add x
    set res {}
    lappend res [a final?   x]
    lappend res [a start?   x]
    lappend res [a symbols@ x]
    a destroy
    set res
} {0 0 {}}


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

test fa-state-${setimpl}-3.0 {state delete} {
    grammar::fa a
    a state add x
    set     res [a states]
    lappend res [a state exists x]
    a state delete x
    lappend res [a states]
    lappend res [a state exists x]
    a destroy
    set res
} {x 1 {} 0}

test fa-state-${setimpl}-3.1 {state delete, variadic} {
    grammar::fa a
    a state add x y
    set     res {}
    lappend res [lsort [a states]]
    lappend res [a state exists x]
    lappend res [a state exists y]
    a state delete x y
    lappend res [a states]
    lappend res [a state exists x]
    lappend res [a state exists y]
    a destroy
    set res
} {{x y} 1 1 {} 0 0}

test fa-state-${setimpl}-3.2 {state delete, loop} {
    grammar::fa a
    a state  add a
    a symbol add @
    a next a @ --> a
    a state delete a
    a destroy
} {}

test fa-state-${setimpl}-3.3 {state delete, inbound transition} {
    grammar::fa a
    gen xyz!-=
    set res [a next x @]
    a state delete y
    lappend res [a next x @]
    a destroy
    set res
} {y {}}


test fa-state-${setimpl}-3.4 {state delete, outbound transition} {
    grammar::fa a
    gen xy-
    a state delete x
    a state delete y
    a symbol delete @
    a destroy
    set res {}
} {}


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


test fa-state-${setimpl}-4.0 {state, exists} {
    grammar::fa a
    set res [a state exists x]
    a destroy
    set res
} 0


test fa-state-${setimpl}-4.1 {state, exists} {
    grammar::fa a
    a state add x
    set res [a state exists x]
    a destroy
    set res
} 1


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


test fa-state-${setimpl}-5.4 {state rename} {
    grammar::fa a
    a state add x y
    a state rename x z
    set res [a serialize]
    a destroy
    set res
} {grammar::fa {} {z {0 0 {}} y {0 0 {}}}}


test fa-state-${setimpl}-5.5 {state rename} {
    grammar::fa a
    a state add x y
    a state rename y z
    set res [a serialize]
    a destroy
    set res
} {grammar::fa {} {x {0 0 {}} z {0 0 {}}}}


test fa-state-${setimpl}-5.6 {state rename} {
    grammar::fa a
    a state add x y
    a symbol add @
    a next x @ --> y
    a state rename x z
    set res [a serialize]
    a destroy
    set res
} {grammar::fa @ {z {0 0 {@ y}} y {0 0 {}}}}


test fa-state-${setimpl}-5.7 {state rename} {
    grammar::fa a
    a state add x y
    a symbol add @
    a next x @ --> y
    a state rename y z
    set res [a serialize]
    a destroy
    set res
} {grammar::fa @ {x {0 0 {@ z}} z {0 0 {}}}}


test fa-state-${setimpl}-6.0 {state rename with loop, SF bug 2595296} {
    grammar::fa a
    a state add x
    a symbol add @
    a next x @ --> x
    a state rename x y
    set res [a serialize]
    a destroy
    set res
} {grammar::fa @ {y {0 0 {@ y}}}}


# -------------------------------------------------------------------------
::tcltest::cleanupTests
