Passed
Pull Request — develop (#27)
by Glynn
05:03 queued 02:03
created

GeneralFunctionTest::testCanUseRecordEncoder()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 85
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 57
nc 1
nop 0
dl 0
loc 85
rs 8.9381
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Tests for the StrictMap class.
7
 *
8
 * @since 0.1.0
9
 * @author Glynn Quelch <[email protected]>
10
 */
11
12
require_once dirname(__FILE__, 2) . '/FunctionsLoader.php';
13
14
use PHPUnit\Framework\TestCase;
15
use PinkCrab\FunctionConstructors\Numbers as Num;
16
use PinkCrab\FunctionConstructors\Strings as Str;
17
use PinkCrab\FunctionConstructors\FunctionsLoader;
18
use PinkCrab\FunctionConstructors\GeneralFunctions as Func;
19
20
class ToArrayFixtureClass
21
{
22
    private $propA = 1;
23
    protected $propB = 2;
24
    public $propC = 3;
25
}
26
27
28
/**
29
 * StringFunction class.
30
 */
31
class GeneralFunctionTest extends TestCase
32
{
33
    public function setup(): void
34
    {
35
        FunctionsLoader::include();
36
    }
37
38
    public function testFunctionCompose(): void
39
    {
40
        $function = Func\compose(
41
            Str\replaceWith('1122', '*\/*'),
42
            Str\replaceWith('6677', '=/\='),
43
            Str\prepend('00'),
44
            Str\append('99')
45
        );
46
47
        $this->assertEquals(
48
            '00*\/*334455=/\=8899',
49
            $function('1122334455667788')
50
        );
51
52
        $function = Func\composeSafe(
53
            Str\replaceWith('3344', '*\/*'),
54
            Str\replaceWith('5566', '=/\='),
55
            Str\prepend('00'),
56
            Str\append('99')
57
        );
58
59
        $this->assertEquals(
60
            '001122*\/*=/\=778899',
61
            $function('1122334455667788')
62
        );
63
    }
64
65
    /** @testdox It should be possible to create a function from a collection of other functions. This function should then be given a value, which is passed to the last function, its return is then passed to the second last and repeated until the end of the functions. */
66
    public function testComposeR()
67
    {
68
        $function = Func\composeR(
69
            Str\replaceWith('99', '*\/*'), // 4
70
            Str\replaceWith('00', '=/\='), // 3
71
            Str\prepend('000'), // 2
72
            Str\append('999') // 1
73
        );
74
75
        // 1 = __999
76
        // 2 = 000__999
77
        // 3 = =/\=0__999
78
        // 4 = =/\=0__*\/*9
79
80
        $this->assertEquals(
81
            '=/\=0__*\/*9',
82
            $function('__')
83
        );
84
    }
85
86
    public function testFunctionCompseSafeHandlesNull(): void
87
    {
88
        $reutrnsNull = function ($e) {
89
            return null;
90
        };
91
92
        $function = Func\composeSafe(
93
            Str\replaceWith('3344', '*\/*'),
94
            Str\replaceWith('5566', '=/\='),
95
            $reutrnsNull,
96
            Str\prepend('00'),
97
            Str\append('99')
98
        );
99
        $this->assertNull($function('1122334455667788'));
100
    }
101
102
    public function testTypeSafeFunctionalComposer(): void
103
    {
104
        $function = Func\composeTypeSafe(
105
            'is_string',
106
            Str\replaceWith('3344', '*\/*'),
107
            Str\replaceWith('5566', '=/\='),
108
            Str\prepend('00'),
109
            Str\append('99')
110
        );
111
112
        $this->assertEquals(
113
            '001122*\/*=/\=778899',
114
            $function('1122334455667788')
115
        );
116
    }
117
118
    public function testAlwaysReturns()
119
    {
120
        $alwaysHappy = Func\always('Happy');
121
122
        $this->assertEquals('Happy', $alwaysHappy('No'));
123
        $this->assertEquals('Happy', $alwaysHappy(false));
124
        $this->assertEquals('Happy', $alwaysHappy(null));
125
        $this->assertEquals('Happy', $alwaysHappy(new DateTime()));
126
        $this->assertNull(Func\always(null)('NOT NULL'));
127
    }
128
129
    public function testCanUsePipe()
130
    {
131
        $results = Func\pipe(
132
            7,
133
            Num\sum(12),
134
            Num\multiply(4),
135
            Num\subtract(7)
136
        );
137
        $this->assertEquals(69, $results);
138
    }
139
140
    public function testCanUsePipeR()
141
    {
142
        $results = Func\pipeR(
143
            7,
144
            Num\subtract(7),
145
            Num\multiply(4),
146
            Num\sum(12)
147
        );
148
        $this->assertEquals(69, $results);
149
    }
150
151
    public function testCanUsePluckProperty()
152
    {
153
        $data = (object)[
154
            'alpha' => [
155
                'bravo' => (object)[
156
                    'charlie' => [
157
                        'delta' => 'SPOONS'
158
                    ]
159
                ]
160
            ]
161
        ];
162
163
        $getSpoons = Func\pluckProperty('alpha', 'bravo', 'charlie', 'delta');
164
        $getDelta = Func\pluckProperty('alpha', 'bravo', 'charlie');
165
        $this->assertEquals('SPOONS', $getSpoons($data));
166
        $this->assertArrayHasKey('delta', $getDelta($data));
167
        $this->assertContains('SPOONS', $getDelta($data));
168
    }
169
170
    public function testCanUseRecordEncoder()
171
    {
172
        $data = (object)[
173
            'post' => (object)[
174
                'id' => 123,
175
                'title' => 'Lorem ipsum dolor',
176
                'content' => 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Similique iste voluptatum sequi. Officia dignissimos minus ipsum odit, facilis voluptatibus veniam enim molestiae ipsam quae temporibus porro necessitatibus quia non mollitia!',
177
                'date' => (new DateTime())->format('d/m/yy H:m'),
178
                'author' => (object)[
179
                    'userName' => 'someUser12',
180
                    'displayName' => 'Sam Smith'
181
                ],
182
                'url' => 'https://www.url.tld/post/123/lorem-ipsum-dolor'
183
            ],
184
            'comments' => [
185
                (object)[
186
                    'post' => 123,
187
                    'author' => (object)[
188
                    'userName' => 'someUser2',
189
                    'displayName' => 'Jane Jameson',
190
                    'comment' => 'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Hic, illo tempore repudiandae quos vero, vitae aut ullam tenetur officiis accusantium dolor animi ipsa omnis impedit, saepe est harum quisquam sit.',
191
                    'date' => (new DateTime('yesterday'))->format('d/m/yy H:m'),
192
                    ]
193
                ],
194
                (object)[
195
                    'post' => 123,
196
                    'author' => (object)[
197
                    'userName' => 'someUser22',
198
                    'displayName' => 'Barry Burton',
199
                    'comment' => 'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Hic, illo tempore repudiandae quos vero, vitae aut ullam tenetur officiis accusantium dolor animi ipsa omnis impedit, saepe est harum quisquam sit.',
200
                    'date' => (new DateTime('yesterday'))->format('d/m/yy H:m'),
201
                    ]
202
                ]
203
            ],
204
            'shares' => [
205
                'facebook' => 125,
206
                'twitter' => 1458,
207
                'instagram' => 8
208
            ]
209
        ];
210
211
        // Simplified post encoder
212
        $encoder = array(
213
            Func\encodeProperty('id', Func\pluckProperty('post', 'id')),
214
            Func\encodeProperty('title', Func\pluckProperty('post', 'title')),
215
            Func\encodeProperty('url', Func\pluckProperty('post', 'url')),
216
            Func\encodeProperty('author', Func\pluckProperty('post', 'author', 'displayName')),
217
            Func\encodeProperty('comments', Func\composeR('count', Func\getProperty('comments'))),
218
            Func\encodeProperty('totalShares', Func\composeR('array_sum', Func\getProperty('shares'))),
219
            Func\encodeProperty('fakeValue', Func\pluckProperty('i', 'do', 'not', 'exist')),
220
        );
221
222
        // Create a generic stdClass encoder.
223
        $objectBuilder = Func\recordEncoder(new stdClass());
224
        $arrayBuilder = Func\recordEncoder([]);
225
226
227
        // Populte builders with the encoder.
228
        $simplePostCreatorObject = $objectBuilder(...$encoder);
229
        $simplePostCreatorArray = $arrayBuilder(...$encoder);
230
231
        // Build the final array/object
232
        $simpleObject = $simplePostCreatorObject($data);
233
        $simpleArray = $simplePostCreatorArray($data);
234
235
        $this->assertEquals(123, $simpleObject->id);
236
        $this->assertEquals(123, $simpleArray['id']);
237
238
        $this->assertEquals('Lorem ipsum dolor', $simpleObject->title);
239
        $this->assertEquals('Lorem ipsum dolor', $simpleArray['title']);
240
241
        $this->assertEquals('https://www.url.tld/post/123/lorem-ipsum-dolor', $simpleObject->url);
242
        $this->assertEquals('https://www.url.tld/post/123/lorem-ipsum-dolor', $simpleArray['url']);
243
244
        $this->assertEquals('Sam Smith', $simpleObject->author);
245
        $this->assertEquals('Sam Smith', $simpleArray['author']);
246
247
        $this->assertEquals(2, $simpleObject->comments);
248
        $this->assertEquals(2, $simpleArray['comments']);
249
250
        $this->assertEquals(1591, $simpleObject->totalShares);
251
        $this->assertEquals(1591, $simpleArray['totalShares']);
252
253
        $this->assertNull($simpleObject->fakeValue);
254
        $this->assertNull($simpleArray['fakeValue']);
255
    }
256
257
    /**
258
     * Test that the invoker can be called.
259
     *
260
     * @return void
261
     */
262
    public function testCanInvokeCallables()
263
    {
264
        $doubleAnyNumber = Func\invoker(Func\compose(
265
            Num\sum(12),
266
            Num\multiply(4),
267
            Num\subtract(7)
268
        ));
269
270
        $this->assertEquals(69, $doubleAnyNumber(7));
271
    }
272
273
    public function testCanUseToArrayForObjects()
274
    {
275
        // Create the simple to array wrapper.
276
        $toArrray = Func\toArray();
277
278
        // Test with valid stdClass.
279
        $obj = new stdClass();
280
        $obj->propA = 1;
281
        $obj->propB = 2;
282
        $this->assertArrayHasKey('propA', $toArrray($obj));
283
        $this->assertEquals(1, $toArrray($obj)['propA']);
284
        $this->assertArrayHasKey('propB', $toArrray($obj));
285
        $this->assertEquals(2, $toArrray($obj)['propB']);
286
287
        // Test only valid public properties.
288
        $obj = new ToArrayFixtureClass();
289
        $this->assertArrayNotHasKey('propA', $toArrray($obj));
290
        $this->assertArrayNotHasKey('propB', $toArrray($obj));
291
        $this->assertArrayHasKey('propC', $toArrray($obj));
292
        $this->assertEquals(3, $toArrray($obj)['propC']);
293
294
        // Check it returns blank array if any other value passed.
295
        $this->assertEmpty($toArrray(false));
296
        $this->assertEmpty($toArrray(null));
297
        $this->assertEmpty($toArrray([1,2,3,4]));
298
        $this->assertEmpty($toArrray(1));
299
        $this->assertEmpty($toArrray(2.5));
300
        $this->assertEmpty($toArrray('STRING'));
301
    }
302
}
303