The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
use strict;
use warnings;

# this covers the exact same stuff from 01-mock.t
# but uses more than one method to override using "methods"

use Test::More;
use Test::TinyMocker;

{

    package Foo::Bar;
    sub baz {"day"}
    sub qux {"way"}
}

# original value
is Foo::Bar::baz(), "day", "first initial value is ok";
is Foo::Bar::qux(), "way", "second initial value is ok";

# basic syntax
mock( 'Foo::Bar', [ 'baz', 'qux' ], sub { return $_[0] + 1 } );
cmp_ok Foo::Bar::baz(1), '==', 2, "basic syntax for baz";
cmp_ok Foo::Bar::qux(1), '==', 2, "basic syntax for qux";

mock 'Foo::Bar' => methods [ 'baz', 'qux' ] => should {"night"};
is Foo::Bar::baz(), "night", "static mocked value for baz";
is Foo::Bar::qux(), "night", "static mocked value for qux";

my $counter = 0;

mock 'Foo::Bar' => methods [ 'baz', 'qux' ] => should { $counter++; };

cmp_ok Foo::Bar::baz(), '==', 0, "dynamic mocked value for baz";
cmp_ok Foo::Bar::qux(), '==', 1, "dynamic mocked value for qux";
cmp_ok Foo::Bar::baz(), '==', 2, "dynamic mocked value for baz";
cmp_ok Foo::Bar::qux(), '==', 3, "dynamic mocked value for qux";

mock( 'Foo::Bar::baz', sub { return $_[0] + 3 } );
mock( 'Foo::Bar::qux', sub { return $_[0] + 3 } );
cmp_ok Foo::Bar::baz(1), '==', 4, "2 args syntax for baz";
cmp_ok Foo::Bar::qux(1), '==', 4, "2 args syntax for qux";

mock [ 'Foo::Bar::baz', 'Foo::Bar::qux' ] => should { $_[0] + 2 };
is Foo::Bar::baz(1), 3, "2 args syntax with sugar for baz";
is Foo::Bar::qux(1), 3, "2 args syntax with sugar for qux";

eval {mock};
like( $@, qr{useless use of mock with one},
    "no call of mock without parameter" );

eval { mock 'Foo' };
like( $@, qr{useless use of mock with one},
    "no call of mock with one parameter" );

eval { mock [ 'Foo', 'Bar' ] };
like( $@, qr{useless use of mock with one},
    "no call of mock with one parameter" );

eval {
    mock 'Foo::Bar' => method 'faked' => should {return};
};
like( $@, qr{unknown symbol:}, "no mock non exists function" );

eval {
    mock 'Foo::Bar' => methods [ 'faked', 'baked' ] => should {return};
};
like( $@, qr{unknown symbol:}, "no mock non exists function" );

done_testing;