1#! perl
2
3use warnings;
4use strict;
5
6use Test::More;
7use Test::Exception;
8use Interchange6::Cart::Cost;
9
10{
11    package CostsConsumer;
12    use Moo;
13    with 'Interchange6::Role::Costs';
14    use namespace::clean;
15
16    has subtotal => ( is => 'ro' );
17}
18
19my ( $obj, $cost, @costs );
20
21lives_ok { $obj = CostsConsumer->new( subtotal => 10 ) }
22"create object with subtotal 10";
23
24cmp_ok( $obj->subtotal, '==', 10, "subtotal is 10" );
25cmp_ok( $obj->total,    '==', 10, "total is 10" );
26
27lives_ok { $obj = CostsConsumer->new( subtotal => 20 ) }
28"create object with subtotal 20";
29
30cmp_ok( $obj->subtotal, '==', 20, "subtotal is 20" );
31ok( !$obj->has_total, "has_total false" );
32cmp_ok( $obj->total, '==', 20, "total is 20" );
33ok( $obj->has_total, "has_total true" );
34
35cmp_ok( $obj->cost_count,       '==', 0, "cost_count is 0" );
36cmp_ok( scalar $obj->get_costs, '==', 0, "get_costs is empty list" );
37
38throws_ok { $obj->apply_cost } qr/argument to apply_cost undefined/,
39  "fail apply_cost with no args";
40
41throws_ok { $obj->apply_cost($obj) }
42qr{Single parameters to new\(\) must be a HASH ref data},
43  "fail apply_cost bad obj as arg";
44
45lives_ok { $cost = Interchange6::Cart::Cost->new( name => "Cost1", amount => 12 ) }
46"create a Cost object with name 'Cost1' and amount 12";
47
48lives_ok { $obj->apply_cost($cost) } "apply_cost Cost object";
49ok( !$obj->has_total, "has_total false" );
50
51cmp_ok( $obj->subtotal,   '==', 20, "subtotal is 20" );
52cmp_ok( $obj->total,      '==', 32, "total is 32" );
53cmp_ok( $obj->cost_count, '==', 1,  "cost_count is 1" );
54
55lives_ok { $cost = Interchange6::Cart::Cost->new( name => "Cost2", amount => 0.1, relative => 1 ) }
56"create a Cost object with name 'Cost2', amount 0.1 and relative => 1";
57
58lives_ok { $obj->apply_cost($cost) } "cost_push Cost object";
59ok( !$obj->has_total, "has_total false" );
60
61cmp_ok( $obj->subtotal,   '==', 20, "subtotal is 20" );
62cmp_ok( $obj->total,      '==', 34, "total is 34" );
63cmp_ok( $obj->cost_count, '==', 2,  "cost_count is 2" );
64
65lives_ok { $cost = $obj->cost_get(0) } "get cost at index 0";
66cmp_ok( $cost->current_amount, '==', 12,      "current_amount is 12" );
67cmp_ok( $cost->name,           'eq', "Cost1", "name is Cost1" );
68
69lives_ok { $cost = $obj->cost_get(1) } "get cost at index 1";
70cmp_ok( $cost->current_amount, '==', 2,       "current_amount is 2" );
71cmp_ok( $cost->name,           'eq', "Cost2", "name is Cost2" );
72
73lives_ok {
74    $cost = Interchange6::Cart::Cost->new(
75        name      => "Cost3",
76        amount    => 0.1,
77        relative  => 1,
78        inclusive => 1
79      )
80}
81"create Cost obj with name 'Cost3', amount 0.1, relative => 1, inclusive => 1";
82
83lives_ok { $obj->cost_set( 1, $cost ) } "set_cost at index 1 to Cost3 obj";
84ok( !$obj->has_total, "has_total false" );
85
86cmp_ok( $obj->subtotal,   '==', 20, "subtotal is 20" );
87cmp_ok( $obj->total,      '==', 32, "total is 32" );
88cmp_ok( $obj->cost_count, '==', 2,  "cost_count is 2" );
89ok( $obj->has_total, "has_total true" );
90
91lives_ok { @costs = $obj->get_costs } "get_costs";
92isa_ok( $costs[0], 'Interchange6::Cart::Cost', "obj at index 0" );
93cmp_ok( $costs[0]->name, 'eq', "Cost1", "obj at index 0 name is Cost1" );
94isa_ok( $costs[1], 'Interchange6::Cart::Cost', "obj at index 1" );
95cmp_ok( $costs[1]->name, 'eq', "Cost3", "obj at index 1 name is Cost3" );
96
97lives_ok { $obj->clear_costs } "clear_costs";
98ok( !$obj->has_total, "has_total false" );
99cmp_ok( $obj->subtotal, '==', 20, "subtotal is 20" );
100cmp_ok( $obj->total,    '==', 20, "total is 20" );
101ok( $obj->has_total, "has_total true" );
102lives_ok { $obj->clear_total } "clear_total";
103ok( !$obj->has_total, "has_total false" );
104cmp_ok( $obj->total, '==', 20, "total is 20" );
105
106lives_ok { $obj->apply_cost( { name => "New1", amount => 5 } ) }
107"apply_cost with args as hashref";
108
109lives_ok { $obj->apply_cost( name => "New2", amount => 2 ) }
110"apply_cost with args as hash";
111
112cmp_ok( $obj->cost_count, '==', 2,  "cost_count is 2" );
113cmp_ok( $obj->total,      '==', 27, "total is 27" );
114
115lives_ok { $cost = $obj->cost("New1") } "call cost New1";
116cmp_ok( $cost, "==", 5, "amount is good" );
117
118lives_ok { $cost = $obj->cost(1) } "call cost 1";
119cmp_ok( $cost, "==", 2, "amount is good" );
120
121throws_ok { $obj->cost } qr/position or name required/,
122  "fail call cost with no args";
123
124throws_ok { $obj->cost(2) } qr/Bad argument to cost/,
125  "fail call cost with index that doesn't exist";
126
127throws_ok { $obj->cost("") } qr/Bad argument to cost/,
128  "fail call cost with empty name";
129
130throws_ok { $obj->cost("BadName") } qr/Bad argument to cost/,
131  "fail call cost with name that doesn't exist";
132
133lives_ok { $obj->clear_costs } "clear_costs";
134
135lives_ok { $obj->apply_cost( name => "Discount", amount => -5, compound => 1 ) }
136"apply_cost Discount -5 compound";
137
138cmp_ok( $obj->total, '==', 15, "total is 15" );
139
140lives_ok { $obj->apply_cost( name => "Shipping", amount => 2, compound => 1 ) }
141"apply_cost Shipping 2 compound";
142
143cmp_ok( $obj->total, '==', 17, "total is 17" );
144
145lives_ok {
146    $obj->apply_cost(
147        name      => "Tax",
148        amount    => 0.20,
149        relative  => 1,
150      )
151}
152"apply_cost Tax 0.20 relative";
153
154cmp_ok( $obj->total, '==', 20.40, "total is 20.40" );
155
156done_testing;
157