
// basics:

guard-default-basic-1 {
    .m(1)                   {case:     1}
    .m(@x) when (default()) {default: @x}

    &-1 {.m(1)}
    &-2 {.m(2)}
}

guard-default-basic-2 {
    .m(1)                   {case:     1}
    .m(2)                   {case:     2}
    .m(3)                   {case:     3}
    .m(@x) when (default()) {default: @x}

    &-0 {.m(0)}
    &-2 {.m(2)}
}

guard-default-basic-3 {
    .m(@x) when (@x = 1)    {case:     1}
    .m(2)                   {case:     2}
    .m(@x) when (@x = 3)    {case:     3}
    .m(@x) when (default()) {default: @x}

    &-0 {.m(0)}
    &-2 {.m(2)}
    &-3 {.m(3)}
}

guard-default-definition-order {
    .m(@x) when (default()) {default: @x}
    .m(@x) when (@x = 1)    {case:     1}
    .m(2)                   {case:     2}
    .m(@x) when (@x = 3)    {case:     3}

    &-0 {.m(0)}
    &-2 {.m(2)}
    &-2 {.m(3)}
}

// out of guard:

guard-default-out-of-guard {
    .m(1)                              {case-1:   1}
    .m(@x: default()) when (default()) {default: @x}
    
    &-0 {
        case-0: default();
        .m(1);
        .m(2);
        case-2: default();
    }
    &-1 {.m(default())}
    &-2 {.m()}
}

// expressions:

guard-default-expr-not {
    .m(1)                      {case:     1}
    .m(@x) when not(default()) {default: @x}

    &-1 {.m(1)}
    &-2 {.m(2)}
}

guard-default-expr-eq {
    .m(@x) when (@x = true)      {case:    @x}
    .m(@x) when (@x = false)     {case:    @x}
    .m(@x) when (@x = default()) {default: @x}

    &-true  {.m(true)}
    &-false {.m(false)}
}

guard-default-expr-or {
    .m(1)                             {case:     1}
    .m(2)                             {case:     2}
    .m(@x) when (default()), (@x = 2) {default: @x}

    &-1 {.m(1)}
    &-2 {.m(2)}
    &-3 {.m(3)}
}

guard-default-expr-and {
    .m(1)                                {case:     1}
    .m(2)                                {case:     2}
    .m(@x) when (default()) and (@x = 3) {default: @x}

    &-1 {.m(1)}
    &-2 {.m(2)}
    &-3 {.m(3)}
    &-4 {.m(4)}
}

guard-default-expr-always {
    .m(1)                                   {case:     1}
    .m(@x) when (default()), not(default()) {default: @x} // always match

    &-1 {.m(1)}
    &-2 {.m(2)}
}

guard-default-expr-never {
    .m(1)                                      {case:     1}
    .m(@x) when (default()) and not(default()) {default: @x} // never match

    &-1 {.m(1)}
    &-2 {.m(2)}
}


// not conflicting multiple default() uses:

guard-default-multi-1 {
    .m(0)                   {case:       0}
    .m(@x) when (default()) {default-1: @x}
    .m(2)  when (default()) {default-2: @x}

    &-0 {.m(0)}
    &-1 {.m(1)}
}

guard-default-multi-2 {
    .m(1, @x)   when (default()) {default-1: @x}
    .m(2, @x)   when (default()) {default-2: @x}
    .m(@x, yes) when (default()) {default-3: @x}

    &-1 {.m(1, no)}
    &-2 {.m(2, no)}
    &-3 {.m(3, yes)}
}

guard-default-multi-3 {
    .m(red)                                    {case-1: darkred}
    .m(blue)                                   {case-2: darkblue}
    .m(@x) when (iscolor(@x)) and (default())  {default-color: @x}
    .m('foo')                                  {case-1: I am 'foo'}
    .m('bar')                                  {case-2: I am 'bar'}
    .m(@x) when (isstring(@x)) and (default()) {default-string: I am @x}

    &-blue  {.m(blue)}
    &-green {.m(green)}
    &-foo   {.m('foo')}
    &-baz   {.m('baz')}
}

guard-default-multi-4 {
    .m(@x) when (default()), not(default())    {always: @x}
    .m(@x) when (default()) and not(default()) {never:  @x}
    .m(2)                                      {case:    2}
    
    .m(1);
    .m(2);
}

guard-default-not-ambiguos-2 {
    .m(@x)                     {case:         1}
    .m(@x) when (default())    {default:     @x}
    .m(@x) when not(default()) {not-default: @x}

    .m(2);
}

guard-default-not-ambiguos-3 {
    .m(@x)                     {case:           1}
    .m(@x) when not(default()) {not-default-1: @x}
    .m(@x) when not(default()) {not-default-2: @x}

    .m(2);
}

// default & scope

guard-default-scopes {
    .s1() {.m(@v)                  {1: no condition}}
    .s2() {.m(@v) when (@v)        {2: when true}}
    .s3() {.m(@v) when (default()) {3: when default}}

    &-3 {
        .s2();
        .s3();
        .m(false);
    }
    
    &-1 {
        .s1();
        .s3();
        .m(false);
    }
}
