├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml.dist
├── psalm.xml
├── src
└── SternTrait.php
└── tests
├── autoload.php
├── phpunit
└── WeakSternTest.php
└── test-classes
└── Weak.php
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on: [push]
4 |
5 | jobs:
6 | old:
7 | name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
8 | runs-on: ${{ matrix.operating-system }}
9 | strategy:
10 | matrix:
11 | operating-system: ['ubuntu-18.04']
12 | php-versions: ['7.0']
13 | phpunit-versions: ['6.5.14']
14 | steps:
15 | - name: Checkout
16 | uses: actions/checkout@v2
17 |
18 | - name: Setup PHP
19 | uses: shivammathur/setup-php@v2
20 | with:
21 | php-version: ${{ matrix.php-versions }}
22 | extensions: mbstring, intl
23 | ini-values: post_max_size=256M, max_execution_time=180
24 | tools: psalm, phpunit:${{ matrix.phpunit-versions }}
25 |
26 | - name: Fix permissions
27 | run: sudo chmod -R 0777 .
28 |
29 | - name: Install dependencies
30 | run: composer self-update --1; composer install
31 |
32 | - name: PHPUnit tests
33 | uses: php-actions/phpunit@v2
34 | with:
35 | memory_limit: 256M
36 |
37 | moderate:
38 | name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
39 | runs-on: ${{ matrix.operating-system }}
40 | strategy:
41 | matrix:
42 | operating-system: ['ubuntu-latest']
43 | php-versions: ['7.1', '7.2', '7.3']
44 | phpunit-versions: ['latest']
45 | steps:
46 | - name: Checkout
47 | uses: actions/checkout@v2
48 |
49 | - name: Setup PHP
50 | uses: shivammathur/setup-php@v2
51 | with:
52 | php-version: ${{ matrix.php-versions }}
53 | extensions: mbstring, intl, sodium
54 | ini-values: post_max_size=256M, max_execution_time=180
55 | tools: psalm, phpunit:${{ matrix.phpunit-versions }}
56 |
57 | - name: Fix permissions
58 | run: sudo chmod -R 0777 .
59 |
60 | - name: Install dependencies
61 | run: composer install
62 |
63 | - name: PHPUnit tests
64 | uses: php-actions/phpunit@v2
65 | timeout-minutes: 30
66 | with:
67 | memory_limit: 256M
68 |
69 | modern:
70 | name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
71 | runs-on: ${{ matrix.operating-system }}
72 | strategy:
73 | matrix:
74 | operating-system: ['ubuntu-latest']
75 | php-versions: ['7.4', '8.0', '8.1']
76 | phpunit-versions: ['latest']
77 | steps:
78 | - name: Checkout
79 | uses: actions/checkout@v2
80 |
81 | - name: Setup PHP
82 | uses: shivammathur/setup-php@v2
83 | with:
84 | php-version: ${{ matrix.php-versions }}
85 | extensions: mbstring, intl, sodium
86 | ini-values: post_max_size=256M, max_execution_time=180
87 | tools: psalm, phpunit:${{ matrix.phpunit-versions }}
88 |
89 | - name: Fix permissions
90 | run: sudo chmod -R 0777 .
91 |
92 | - name: Install dependencies
93 | run: composer install
94 |
95 | - name: PHPUnit tests
96 | uses: php-actions/phpunit@v2
97 | timeout-minutes: 30
98 | with:
99 | memory_limit: 256M
100 |
101 | - name: Install Psalm
102 | run: composer require --dev vimeo/psalm:^4
103 |
104 | - name: Static Analysis
105 | run: vendor/bin/psalm
106 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /composer.lock
2 | /vendor/
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Paragon Initiative Enterprises
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Stern
2 |
3 | [](https://github.com/paragonie/stern/actions)
4 | [](https://packagist.org/packages/paragonie/stern)
5 | [](https://packagist.org/packages/paragonie/stern)
6 | [](https://packagist.org/packages/paragonie/stern)
7 |
8 | Stern lets you built type-safe PHP projects, even if your project's users aren't writing type-safe code.
9 |
10 | **Requires PHP 7+**
11 |
12 | ## Usage
13 |
14 | Using Stern is simply:
15 |
16 | 1. Make your class use the `SternTrait`.
17 | 2. Rename your methods from `whateverName` to `strictWhateverName`.
18 | 3. Enjoy strict-typing whether your users like it or not.
19 |
20 | ## Example
21 |
22 | ```diff
23 |
2 |
12 |
13 |
14 | ./src
15 |
16 |
17 |
18 |
19 | ./tests/phpunit
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/psalm.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/SternTrait.php:
--------------------------------------------------------------------------------
1 | {'strict' . $name}(...$arguments);
21 | }
22 |
23 | throw new \Error(
24 | \sprintf('Destination proxy method %s not found on class %s', 'strict' . $name, \get_class($this))
25 | );
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/tests/autoload.php:
--------------------------------------------------------------------------------
1 | assertSame(true, $weak->weakBool(true));
15 | $this->assertSame(false, $weak->weakBool(false));
16 | try {
17 | $weak->weakBool(null);
18 | $this->fail('Expected a TypeError');
19 | } catch (Error $ex) {
20 | $this->assertTrue($ex instanceof TypeError);
21 | }
22 | try {
23 | $weak->weakBool(0);
24 | $this->fail('Expected a TypeError');
25 | } catch (Error $ex) {
26 | $this->assertTrue($ex instanceof TypeError);
27 | }
28 | }
29 |
30 | public function testWeakFloat()
31 | {
32 | $weak = new Weak();
33 | $this->assertSame(123.45, $weak->weakFloat(123.45));
34 | $this->assertSame(12345.0, $weak->weakFloat(12345.0));
35 |
36 | try {
37 | $weak->weakFloat('123.44');
38 | $this->fail('Expected a TypeError');
39 | } catch (Error $ex) {
40 | $this->assertTrue($ex instanceof TypeError);
41 | }
42 | }
43 |
44 | public function testWeakInt()
45 | {
46 | $weak = new Weak();
47 | $this->assertSame(12345, $weak->weakInt(12344));
48 |
49 | try {
50 | $weak->weakInt('12344');
51 | $this->fail('Expected a TypeError');
52 | } catch (Error $ex) {
53 | $this->assertTrue($ex instanceof TypeError);
54 | }
55 | }
56 |
57 | public function testWeakString()
58 | {
59 | $weak = new Weak();
60 | $this->assertSame('nccyr', $weak->weakString('apple'));
61 | $this->assertSame('NCCYR', $weak->weakString('APPLE'));
62 | $this->assertSame('12345', $weak->weakString('12345'));
63 |
64 | try {
65 | $weak->weakString(12345);
66 | $this->fail('Expected a TypeError');
67 | } catch (Error $ex) {
68 | $this->assertTrue($ex instanceof TypeError);
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/tests/test-classes/Weak.php:
--------------------------------------------------------------------------------
1 |