File Coverage

blib/lib/WWW/Shopify/Liquid/Tag/Assign.pm
Criterion Covered Total %
statement 53 63 84.1
branch 36 54 66.6
condition 19 39 48.7
subroutine 7 9 77.7
pod 0 4 0.0
total 115 169 68.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2 37     37   350382 use strict;
  37         114  
  37         1569  
3 37     37   248 use warnings;
  37         102  
  37         1377  
4              
5 37     37   10869 use WWW::Shopify::Liquid::Tag;
  37         117  
  37         1334  
6              
7             package WWW::Shopify::Liquid::Tag::Assign;
8 37     37   264 use base 'WWW::Shopify::Liquid::Tag::Free';
  37         98  
  37         12417  
9 37     37   291 use Scalar::Util qw(looks_like_number);
  37         98  
  37         30857  
10 0     0 0 0 sub min_arguments { return 1; }
11 0     0 0 0 sub max_arguments { return 1; }
12             sub verify {
13 139     139 0 393 my ($self) = @_;
14             die new WWW::Shopify::Liquid::Exception::Parser::Arguments($self, "Requires assignment operator to be the first thing in an assign tag.") unless
15 139 50       795 $self->{arguments}->[0]->isa('WWW::Shopify::Liquid::Operator::Assignment');
16             die new WWW::Shopify::Liquid::Exception::Parser::Arguments($self, "Requires variable for what you're assigning to.") unless
17 139 50       815 $self->{arguments}->[0]->{operands}->[0]->isa('WWW::Shopify::Liquid::Token::Variable');
18             }
19             sub process {
20 70     70 0 242 my ($self, $hash, $action, $pipeline) = @_;
21 70 50       159 my @vars = map { $self->is_processed($_) ? $_ : $_->$action($pipeline, $hash) } @{$self->{arguments}->[0]->{operands}->[0]->{core}};
  78         326  
  70         321  
22 70 50 66     336 return $self if $action eq "optimize" && int(grep { !$self->is_processed($_) } @vars) > 0;
  17         72  
23            
24            
25 70         149 my $inner_hash = $hash;
26 70         281 for (0..$#vars-1) {
27 8 50 66     87 return $self if ref($inner_hash) && ref($inner_hash) eq "HASH" && !exists $inner_hash->{$vars[$_]} && $action eq 'optimize';
      100        
      66        
28 8 100 66     48 if (looks_like_number($vars[$_]) && ref($inner_hash) && ref($inner_hash) eq "ARRAY") {
      66        
29 1 50       5 $inner_hash->[$vars[$_]] = {} if !defined $inner_hash->[$vars[$_]];
30 1         3 $inner_hash = $inner_hash->[$vars[$_]];
31             } else {
32 7 100       23 $inner_hash->{$vars[$_]} = {} if !exists $inner_hash->{$vars[$_]};
33 7         20 $inner_hash = $inner_hash->{$vars[$_]};
34             }
35             }
36            
37            
38 70         216 my $result = $self->{arguments}->[0]->{operands}->[1];
39             # For now, only do renders.
40 70 100       221 if ($action eq "optimize") {
41 17 100       74 if (exists $inner_hash->{$vars[-1]}) {
42 1         6 my $value = delete $inner_hash->{$vars[-1]};
43 1 50       6 $result = $result->$action($pipeline, $hash) if !$self->is_processed($result);
44 1 50       8 $inner_hash->{$vars[-1]} = $result if $self->is_processed($result);
45             } else {
46 16 100       64 $result = $result->$action($pipeline, $hash) if !$self->is_processed($result);
47             }
48 17 100       72 $self->{arguments}->[0]->{operands}->[1] = $result if $self->is_processed($result);
49             # If we run across something that should be assigned, we must delete it in the hash to preserve uncertainty.
50             # OK, no. We still return ourselves, but we do a bit of a deeper analysis. If the assignment is out the in the open, we assign.
51             # If the assignment is contingent upon a conditional, (i.e. inside something that isn't fully resolved). Then we delete it.
52 17         125 $pipeline->flag_conditional_uncertainty(\@vars);
53 17 100       63 $inner_hash->{$vars[-1]} = $result if $self->is_processed($result);
54 17 100 66     87 return undef if $pipeline->remove_assignment && !defined $pipeline->conditional_state;
55 16         79 return $self;
56             } else {
57 53 50       170 $result = $result->$action($pipeline, $hash) if !$self->is_processed($result);
58             }
59 53 50       189 return $self unless $self->is_processed($result);
60            
61 53         140 my $assignment = $self->{arguments}->[0];
62 53 100 66     332 if (looks_like_number($vars[-1]) && ref($inner_hash) && ref($inner_hash) eq "ARRAY") {
      66        
63 3 50       41 if ($assignment->isa('WWW::Shopify::Liquid::Operator::PlusAssignment')) {
    50          
    50          
    50          
64 0   0     0 $inner_hash->[$vars[-1]] += ($result || 0);
65             } elsif ($assignment->isa('WWW::Shopify::Liquid::Operator::MinusAssignment')) {
66 0   0     0 $inner_hash->[$vars[-1]] -= ($result || 0);
67             } elsif ($assignment->isa('WWW::Shopify::Liquid::Operator::MultiplyAssignment')) {
68 0   0     0 $inner_hash->[$vars[-1]] *= ($result || 0);
69             } elsif ($assignment->isa('WWW::Shopify::Liquid::Operator::DivideAssignment')) {
70 0         0 $inner_hash->[$vars[-1]] /= $result;
71             } else {
72 3         7 $inner_hash->[$vars[-1]] = $result;
73             }
74             } else {
75 50 50       684 if ($assignment->isa('WWW::Shopify::Liquid::Operator::PlusAssignment')) {
    50          
    50          
    50          
76 0   0     0 $inner_hash->{$vars[-1]} += ($result || 0);
77             } elsif ($assignment->isa('WWW::Shopify::Liquid::Operator::MinusAssignment')) {
78 0   0     0 $inner_hash->{$vars[-1]} -= ($result || 0);
79             } elsif ($assignment->isa('WWW::Shopify::Liquid::Operator::MultiplyAssignment')) {
80 0   0     0 $inner_hash->{$vars[-1]} *= ($result || 0);
81             } elsif ($assignment->isa('WWW::Shopify::Liquid::Operator::DivideAssignment')) {
82 0         0 $inner_hash->{$vars[-1]} /= $result;
83             } else {
84 50         168 $inner_hash->{$vars[-1]} = $result;
85             }
86             }
87 53         197 return '';
88             }
89              
90              
91              
92             1;