#!perl -wT # $Id: currency.t 1731 2007-02-11 20:35:41Z claco $ use strict; use warnings; BEGIN { use lib 't/lib'; use Test::More tests => 118; use Scalar::Util qw/refaddr/; eval 'use Test::MockObject 1.07'; if (!$@) { Test::MockObject->fake_module('Finance::Currency::Convert::WebserviceX' => ( new => sub {return bless {}, shift}, convert => sub {return $_[1]+1.00} )); Test::MockObject->fake_module('MyConverterClass' => ( new => sub {return bless {}, shift}, convert => sub {return $_[1]+2.00} )); }; use_ok('Data::Currency'); }; ## check overloads { my $currency = Data::Currency->new(1); is($currency + 1, 2, 'overloads as numeric'); ok($currency, 'overloads boolean'); is("$currency", '$1.00', 'overloads string'); cmp_ok($currency, '==', 1, 'overloads =='); }; ## as_string/stringify with format { my $currency = Data::Currency->new; isa_ok($currency, 'Data::Currency'); is($currency->value, 0, 'value was set'); is($currency->stringify('FMT_STANDARD'), '0.00 USD', 'stringify to value'); is($currency->code, 'USD', 'code is set'); is($currency->format, 'FMT_COMMON', 'format is not set'); is($currency->name, 'US Dollar', 'got name'); is($currency->converter, undef, 'converter no defined'); }; ## croak as_string/stringify with no code { my $currency = Data::Currency->new; isa_ok($currency, 'Data::Currency'); delete $currency->{'code'}; local $Data::Currency::__cag_code = undef; eval { $currency->stringify; }; like($@, qr/invalid currency code/i); }; ## croak as_string/stringify with bad code { my $currency = Data::Currency->new; isa_ok($currency, 'Data::Currency'); $currency->{'code'} = 'BAD'; eval { $currency->stringify; }; like($@, qr/invalid currency code/i); }; ## croak convert with bad target code { my $currency = Data::Currency->new; isa_ok($currency, 'Data::Currency'); eval { $currency->convert('BAD'); }; like($@, qr/invalid currency code/i); }; ## croak convert with bad source code { my $currency = Data::Currency->new; isa_ok($currency, 'Data::Currency'); $currency->{'code'} = 'BAD'; eval { $currency->convert('CAD'); }; like($@, qr/invalid currency code/i); }; ## default to FMT_COMMON when no format is set in stringify { my $currency = Data::Currency->new(1.23); $currency->format(undef); Data::Currency->format(undef); is($currency->format, undef); delete $currency->{'format'}; is($currency->format, undef); is($currency->stringify, '$1.23'); Data::Currency->format('FMT_COMMON'); is($currency->format, 'FMT_COMMON'); }; ## create with no value { my $currency = Data::Currency->new; isa_ok($currency, 'Data::Currency'); is($currency->value, 0, 'value was set'); is($currency->stringify, '$0.00', 'stringify to value'); is($currency->code, 'USD', 'code is set'); is($currency->format, 'FMT_COMMON', 'format is not set'); is($currency->name, 'US Dollar', 'got name'); is($currency->converter, undef, 'converter no defined'); }; ## create new with no options { my $currency = Data::Currency->new(1.23); isa_ok($currency, 'Data::Currency'); is($currency->value, 1.23, 'value was set'); is($currency->stringify, '$1.23', 'stringify to value'); is($currency->code, 'USD', 'code is set'); is($currency->format, 'FMT_COMMON', 'format is set'); is($currency->name, 'US Dollar', 'got name'); is($currency->converter, undef, 'converter no defined'); }; ## create new with code/format { my $currency = Data::Currency->new(1.23, 'CAD', 'FMT_STANDARD'); isa_ok($currency, 'Data::Currency'); is($currency->value, 1.23, 'value was set'); is($currency->stringify, '1.23 CAD', 'stringify to string'); is($currency->code, 'CAD', 'code was set'); is($currency->format, 'FMT_STANDARD', 'format was set'); is($currency->converter, undef, 'converter no defined'); }; ## create new with code/format as a hash { my $currency = Data::Currency->new({ value => 1.23, code => 'CAD', format => 'FMT_STANDARD' }); isa_ok($currency, 'Data::Currency'); is($currency->value, 1.23, 'value was set'); is($currency->stringify, '1.23 CAD', 'stringify to string'); is($currency->code, 'CAD', 'code was set'); is($currency->format, 'FMT_STANDARD', 'format was set'); is($currency->converter, undef, 'converter no defined'); }; ## create new with code/format as a hash w/ bad data { my $currency = Data::Currency->new({ value => undef, code => undef, format => undef }); isa_ok($currency, 'Data::Currency'); is($currency->value, 0, 'value was set'); is($currency->stringify, '$0.00', 'stringify to string'); is($currency->code, 'USD', 'code was set'); is($currency->format, 'FMT_COMMON', 'format was set'); is($currency->converter, undef, 'converter no defined'); }; ## croak when bad currency code is set in new { eval { my $currency = Data::Currency->new(1.23, 'BAD'); }; like($@, qr/invalid currency code/i); }; ## create and set code/format { my $currency = Data::Currency->new(1.23); isa_ok($currency, 'Data::Currency'); is($currency->value, 1.23, 'value was set'); is($currency->stringify, '$1.23', 'stringify to string'); is($currency->code, 'USD', 'code is set'); is($currency->converter, undef, 'converter no defined'); $currency->code('CAD'); is($currency->code, 'CAD', 'code set'); $currency->format('FMT_STANDARD'); is($currency->format, 'FMT_STANDARD', 'format set'); is($currency->stringify, '1.23 CAD', 'stringify to string'); }; ## tcroak when bad currency code is set { my $currency = Data::Currency->new(1.23); eval { $currency->code('BAD'); }; like($@, qr/invalid currency code/i); }; ## get name { my $currency = Data::Currency->new(1.23, 'JPY'); isa_ok($currency, 'Data::Currency'); is($currency->code, 'JPY', 'code was set'); is($currency->name, 'Yen', 'got name'); }; ## throw exception when converter_class can't be loaded { eval { Data::Currency->converter_class('Bogus'); }; like($@, qr/Bogus could not be loaded/i); }; ## test convert SKIP: { eval 'use Test::MockObject 1.07'; skip 'Test::MockObject 1.07 not installed', 44 if $@; ## convert with code { my $currency = Data::Currency->new(1.23, 'USD'); isa_ok($currency, 'Data::Currency'); is($currency->value, 1.23, 'value was set'); is($currency->stringify, '$1.23', 'stringify to string'); is($currency->code, 'USD', 'code is set'); is($currency->format, 'FMT_COMMON', 'format is not set'); is($currency->converter, undef, 'converter not defined'); my $converted = $currency->convert('CAD'); isa_ok($currency->converter, 'Finance::Currency::Convert::WebserviceX'); isa_ok($converted, 'Data::Currency'); is($converted->value, 2.23, 'value was set'); is($converted->stringify, '$2.23', 'stringify to value'); is($converted->code, 'CAD', 'code is set'); is($converted->format, 'FMT_COMMON', 'format is set'); }; ## use an existing converter { my $currency = Data::Currency->new(1.23, 'USD'); isa_ok($currency, 'Data::Currency'); is($currency->value, 1.23, 'value was set'); is($currency->stringify, '$1.23', 'stringify to string'); is($currency->code, 'USD', 'code is set'); is($currency->format, 'FMT_COMMON', 'format is not set'); is($currency->converter, undef, 'converter not defined'); $currency->converter(MyConverterClass->new); my $converted = $currency->convert('CAD'); isa_ok($currency->converter, 'MyConverterClass'); isa_ok($converted, 'Data::Currency'); is($converted->value, 3.23, 'value was set'); is($converted->stringify, '$3.23', 'stringify to value'); is($converted->code, 'CAD', 'code is set'); is($converted->format, 'FMT_COMMON', 'format is set'); }; ## test when converter returns nothing { Test::MockObject->fake_module('Finance::Currency::Convert::WebserviceX' => ( new => sub {return bless {}, shift}, convert => sub {} )); my $currency = Data::Currency->new(1.23, 'USD'); my $converted = $currency->convert('CAD'); isa_ok($converted, 'Data::Currency'); is($converted->value, 0, 'value is 0 when converter fails'); is($converted->stringify, '$0.00', 'stringify to value'); is($converted->code, 'CAD', 'code is set'); is($converted->format, 'FMT_COMMON', 'format is not set'); }; ## throw exception when no code is set during convert { my $currency = Data::Currency->new(1.23); eval { $currency->{'code'} = undef; $currency->convert('CAD'); }; like($@, qr/invalid currency code source/i); }; ## throw exception when no code is passed to convert { my $currency = Data::Currency->new(1.23, 'CAD'); eval { $currency->convert; }; like($@, qr/invalid currency code target/i); }; ## return self if to is same as from { my $currency = Data::Currency->new(1.23, 'USD'); isa_ok($currency, 'Data::Currency'); is($currency->value, 1.23, 'value was set'); is($currency->stringify, '$1.23', 'stringify to string'); is($currency->code, 'USD', 'code is set'); is($currency->format, 'FMT_COMMON', 'format is set'); is($currency->converter, undef, 'converter not defined'); my $converted = $currency->convert('USD'); is($currency->converter, undef, 'converter not defined'); is(refaddr $converted, refaddr $currency, 'return self if codes are the same'); isa_ok($converted, 'Data::Currency'); is($converted->value, 1.23, 'value was set'); is($converted->stringify, '$1.23', 'stringify to string'); is($converted->code, 'USD', 'code is set'); is($converted->format, 'FMT_COMMON', 'format is not set'); }; }; ## test loading of utf8 { local $] = 5.007999; my $currency = Data::Currency->new(1.23); isa_ok($currency, 'Data::Currency'); is($currency->stringify, '$1.23', 'still got format'); }; ## set converter_class to nothing, and put it back { Data::Currency->converter_class(undef); is(Data::Currency->converter_class, undef, 'unset converter_class'); Data::Currency->converter_class('Data::Currency'); is(Data::Currency->converter_class, 'Data::Currency', 'set converter_class'); };