Completed
Push — master ( e1b51a...ef7e86 )
by Andrii
05:09
created

FeatureContext::ensureNo()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
/**
3
 * PHP Billing Library
4
 *
5
 * @link      https://github.com/hiqdev/php-billing
6
 * @package   php-billing
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2018, HiQDev (http://hiqdev.com/)
9
 */
10
use Behat\Behat\Context\Context;
11
use hiqdev\php\billing\action\Action;
12
use hiqdev\php\billing\charge\Charge;
13
use hiqdev\php\billing\customer\Customer;
14
use hiqdev\php\billing\formula\FormulaEngine;
15
use hiqdev\php\billing\price\SinglePrice;
16
use hiqdev\php\billing\target\Target;
17
use hiqdev\php\billing\type\Type;
18
use hiqdev\php\units\Quantity;
19
use Money\Currency;
20
use Money\Money;
21
use PHPUnit\Framework\Assert;
22
23
/**
24
 * Defines application features from the specific context.
25
 */
26
class FeatureContext implements Context
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
27
{
28
    protected $engine;
29
30
    protected $customer;
31
    protected $price;
32
    protected $action;
33
    protected $charges;
34
    protected $date;
35
36
    /**
37
     * Initializes context.
38
     */
39
    public function __construct()
40
    {
41
        $this->customer = new Customer(null, 'somebody');
42
    }
43
44
    /**
45
     * @Given /(\S+) (\S+) price is ([0-9.]+) (\w+) per (\w+)/
46
     */
47
    public function priceIs($target, $type, $sum, $currency, $unit)
48
    {
49
        $type = new Type(Type::ANY, $type);
50
        $target = new Target(Target::ANY, $target);
51
        $quantity = Quantity::create($unit, 0);
52
        $sum = new Money($sum*100, new Currency($currency));
53
        $this->price = new SinglePrice(null, $type, $target, null, $quantity, $sum);
54
    }
55
56
    /**
57
     * @Given /action is (\S+) (\w+) ([0-9.]+) (\S+)/
58
     */
59
    public function actionIs($target, $type, $amount, $unit)
60
    {
61
        $type = new Type(Type::ANY, $type);
62
        $target = new Target(Target::ANY, $target);
63
        $quantity = Quantity::create($unit, $amount);
64
        $time = new DateTimeImmutable();
65
        $this->action = new Action(null, $type, $target, $quantity, $this->customer, $time);
66
    }
67
68
    /**
69
     * @Given /formula is (.+)/
70
     */
71
    public function formulaIs($formula)
72
    {
73
        $this->price->setFormula($this->getFormulaEngine()->build($formula));
74
    }
75
76
    protected function getFormulaEngine()
77
    {
78
        if ($this->engine === null) {
79
            $this->engine = new FormulaEngine();
80
        }
81
82
        return $this->engine;
83
    }
84
85
    /**
86
     * @When /action date is ([0-9.-]+)/
87
     */
88
    public function actionDateIs($date)
89
    {
90
        $this->action->setTime(new DateTimeImmutable($date));
91
    }
92
93
    /**
94
     * @Then /(\w+) charge is $/
95
     */
96
    public function emptyCharge($numeral)
97
    {
98
        $this->chargeIs($numeral);
99
    }
100
101
    /**
102
     * @Then /(\w+) charge is (\S+) ([0-9.]+) ([A-Z]{3})$/
103
     */
104
    public function chargeWithSum($numeral, $type = null, $sum = null, $currency = null)
105
    {
106
        $this->chargeIs($numeral, $type, $sum, $currency);
107
    }
108
109
    /**
110
     * @Then /(\w+) charge is (\S+) ([0-9.]+) ([A-Z]{3}) reason (.+)/
111
     */
112
    public function chargeWithReason($numeral, $type = null, $sum = null, $currency = null, $reason = null)
113
    {
114
        $this->chargeIs($numeral, $type, $sum, $currency, $reason);
115
    }
116
117
    public function chargeIs($numeral, $type = null, $sum = null, $currency = null, $reason = null)
118
    {
119
        $no = $this->ensureNo($numeral);
120
        if ($no === 0) {
121
            $this->charges = $this->price->calculateCharges($this->action);
122
        }
123
        $this->assertCharge($this->charges[$no], $type, $sum, $currency, $reason);
124
    }
125
126
    public function assertCharge($charge, $type, $sum, $currency, $reason)
127
    {
128
        if (empty($type) && empty($sum) && empty($currency)) {
129
            Assert::assertNull($charge);
130
            return;
131
        }
132
        Assert::assertInstanceOf(Charge::class, $charge);
133
        Assert::assertSame($type, $charge->getPrice()->getType()->getName());
134
        $money = new Money($sum*100, new Currency($currency));
135
        Assert::assertEquals($money, $charge->getSum());
136
        if ($reason !== null) {
137
            Assert::assertSame($reason, $charge->getComment());
138
        }
139
    }
140
141
    protected $numerals = [
142
        'first'     => 1,
143
        'second'    => 2,
144
        'third'     => 3,
145
        'fourth'    => 4,
146
        'fifth'     => 5,
147
    ];
148
149
    public function ensureNo($numeral)
150
    {
151
        if (empty($this->numerals[$numeral])) {
152
            throw new Exception("wrong numeral '$numeral'");
153
        }
154
155
        return $this->numerals[$numeral] - 1;
156
    }
157
}
158