#!/usr/bin/env perl
use warnings;
use strict;

# Tests for the Perl module IPC::Run3::Shell
# 
# Copyright (c) 2015 Hauke Daempfling (haukex@zero-g.net).
# 
# This library is free software; you can redistribute it and/or modify
# it under the same terms as Perl 5 itself.
# 
# For more information see the "Perl Artistic License",
# which should have been distributed with your copy of Perl.
# Try the command "perldoc perlartistic" or see
# http://perldoc.perl.org/perlartistic.html .

# These are the tests for OverloadTestClasses.pm, not directly IPC::Run3::Shell

use FindBin ();
use lib $FindBin::Bin;
use IPC_Run3_Shell_Testlib;

use Test::More tests=>10;
use Test::Fatal 'exception';

use overload ();
use OverloadTestClasses;
use Scalar::Util 'refaddr';

subtest FakeStringFallback => sub { plan tests=>6;
	my $s = new_ok FakeStringFallback=>["4"];
	is "$s", "149", "overloaded stringify";
	ok !defined overload::Method($s,'0+'), "no overloaded numify";
	ok $s eq "149", "magic eq";
	ok $s == 149, "magic ==";
	is $s+3, 152, "magic add";
};
subtest FakeStringDefault => sub { plan tests=>6;
	my $s = new_ok FakeStringDefault=>["5"];
	is "$s", "258", "overloaded stringify";
	ok !defined overload::Method($s,'0+'), "no overloaded numify";
	like exception { $s eq "258" }, qr/\bno method found\b/, "doesn't eq";
	like exception { $s == 258 }, qr/\bno method found\b/, "doesn't ==";
	like exception { $s+4 }, qr/\bno method found\b/, "doesn't add";
};
subtest FakeStringOnly => sub { plan tests=>6;
	my $s = new_ok FakeStringOnly=>["6"];
	is "$s", "367", "overloaded stringify";
	ok !defined overload::Method($s,'0+'), "no overloaded numify";
	like exception { $s eq "258" }, qr/\bno method found\b/, "doesn't eq";
	like exception { $s == 258 }, qr/\bno method found\b/, "doesn't ==";
	like exception { $s+5 }, qr/\bno method found\b/, "doesn't add";
};

subtest FakeNumberFallback => sub { plan tests=>7;
	my $n = new_ok FakeNumberFallback=>[3];
	ok !defined overload::Method($n,'""'), "no overloaded stringify";
	# Possible To-Do for Later: I'm not sure how to invoke numification directly?
	is overload::Method($n,'0+')->($n), 5, "overloaded numify";
	ok $n == 5, "magic ==";
	ok $n eq "5", "magic eq";
	is "$n", "5", "autogenerated stringify";
	is $n+1, 6, "magic add";
};
subtest FakeNumberDefault => sub { plan tests=>7;
	my $n = new_ok FakeNumberDefault=>[4];
	ok !defined overload::Method($n,'""'), "no overloaded stringify";
	is overload::Method($n,'0+')->($n), 8, "overloaded numify";
	like exception { $n == 8 }, qr/\bno method found\b/, "doesn't ==";
	like exception { $n eq "8" }, qr/\bno method found\b/, "doesn't eq";
	is "$n", "8", "autogenerated stringify";
	like exception { 0+$n }, qr/\bno method found\b/, "doesn't add";
};
subtest FakeNumberOnly => sub { plan tests=>7;
	my $n = new_ok FakeNumberOnly=>[5];
	ok !defined overload::Method($n,'""'), "no overloaded stringify";
	is overload::Method($n,'0+')->($n), 11, "overloaded numify";
	like exception { $n == 11 }, qr/\bno method found\b/, "doesn't ==";
	like exception { $n eq "11" }, qr/\bno method found\b/, "doesn't eq";
	like exception { "$n" }, qr/\bno method found\b/, "doesn't stringify";
	like exception { 0+$n }, qr/\bno method found\b/, "doesn't add";
};

subtest NotStrOrNumish => sub { plan tests=>8;
	my $n = new_ok NotStrOrNumish=>[9];
	ok overload::Overloaded($n), "object has overloading";
	ok !defined overload::Method($n,'""'), "no overloaded stringify";
	ok !defined overload::Method($n,'0+'), "no overloaded numify";
	like exception { $n == 11 }, qr/\bno method found\b/, "doesn't ==";
	like exception { $n eq "11" }, qr/\bno method found\b/, "doesn't eq";
	like exception { "$n" }, qr/\bno method found\b/, "doesn't stringify";
	is $n+4, 12, "can add";
};

subtest NotOverloaded => sub { plan tests=>4;
	my $x = new_ok NotOverloaded=>["foo"];
	ok !overload::Overloaded($x), "no overloading at all";
	like "$x", qr/^NotOverloaded=SCALAR\(0x[a-fA-F0-9]+\)$/, "default Perl stringifcation";
	is $x+0, refaddr($x), "default Perl numification";
};

subtest DiesOnStringify => sub { plan tests=>6;
	my $s = new_ok DiesOnStringify=>["1"];
	like exception { "$s" }, qr/\bARRRGH\b/, "stringify fails";
	ok !defined overload::Method($s,'0+'), "no overloaded numify";
	like exception { $s eq "11" }, qr/\bARRRGH\b/, "eq fails";
	like exception { $s == 11 }, qr/\bARRRGH\b/, "== fails";
	like exception { 0+$s }, qr/\bARRRGH\b/, "add fails";
};
subtest DiesOnNumify => sub { plan tests=>6;
	my $s = new_ok DiesOnNumify=>[1];
	like exception { "$s" }, qr/\bBLAMMO\b/, "stringify fails";
	ok !defined overload::Method($s,'""'), "no overloaded stringify";
	like exception { $s eq "11" }, qr/\bBLAMMO\b/, "eq fails";
	like exception { $s == 11 }, qr/\bBLAMMO\b/, "== fails";
	like exception { 0+$s }, qr/\bBLAMMO\b/, "add fails";
};

