Skip to content

Commit

Permalink
feat: Initial commit (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanschuler authored Jul 19, 2024
2 parents fdec674 + 2b56540 commit d224d94
Show file tree
Hide file tree
Showing 11 changed files with 373 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# The IDE is assumed to use PSR-2 for PHP files.

root = true

[*]
indent_style = space
indent_size = 4
tab_width = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.{yml,yaml}]
indent_size = 2
tab_width = 2
61 changes: 61 additions & 0 deletions .github/workflows/unittests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: unittests

on: [ push, pull_request ]

jobs:
unittests:
name: '[PHP ${{ matrix.php-version }} | Flow ${{ matrix.flow-version }}] Unit Tests'
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
php-version: [ 7.4, 8.2, 8.3 ]
flow-version: [ 7.3, 8.3 ]
exclude:
# Disable Flow 8 on PHP 7, as 8.0 is required
- php-version: 7.4
flow-version: 8.2
# Disable Flow 8 on PHP 7, as 8.0 is required
- php-version: 7.4
flow-version: 8.3

env:
APP_ENV: true
FLOW_CONTEXT: Testing/Unit
FLOW_DIST_FOLDER: flow-base-distribution

steps:
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, xml, json, zlib, iconv, intl, pdo_sqlite
ini-values: opcache.fast_shutdown=0

- name: "Create composer project - No install"
run: composer create-project neos/flow-base-distribution ${{ env.FLOW_DIST_FOLDER }} --prefer-dist --no-progress --no-install "^${{ matrix.flow-version }}"

- name: "Allow neos composer plugin"
run: composer config --no-plugins allow-plugins.neos/composer-plugin true
working-directory: ${{ env.FLOW_DIST_FOLDER }}

- name: "Create composer project - Require behat in compatible version"
run: composer require --dev --no-update "neos/behat:@dev"
working-directory: ${{ env.FLOW_DIST_FOLDER }}

- name: "Create composer project - Install project"
run: composer install
working-directory: ${{ env.FLOW_DIST_FOLDER }}

- name: Checkout code
uses: actions/checkout@v2
with:
path: ${{ env.FLOW_DIST_FOLDER }}/DistributionPackages/Netlogix.Eel.JavaScript

- name: Install netlogix/eel-javascript
run: composer require netlogix/eel-javascript:@dev
working-directory: ${{ env.FLOW_DIST_FOLDER }}

- name: Run tests
run: bin/phpunit -c DistributionPackages/Netlogix.Eel.JavaScript/Tests/phpunit.xml.dist --testsuite="Unit" --bootstrap "Build/BuildEssentials/PhpUnit/UnitTestBootstrap.php"
working-directory: ${{ env.FLOW_DIST_FOLDER }}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.idea/
vendor/
Packages/

composer.lock

Build/

Tests/.phpunit.result.cache
72 changes: 72 additions & 0 deletions Classes/Helper/JavaScriptHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

namespace Netlogix\Eel\JavaScript\Helper;

use MatthiasMullie\Minify\JS as JSMinify;
use Neos\Eel\ProtectedContextAwareInterface;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Core\Bootstrap;
use Neos\Flow\ResourceManagement\Streams\ResourceStreamWrapper;
use ReflectionClass;
use function array_keys;
use function array_reduce;
use function json_encode;
use function sprintf;
use const JSON_PRETTY_PRINT;

/**
* @Flow\Scope("singleton")
*/
final class JavaScriptHelper implements ProtectedContextAwareInterface
{
public function embed(string $path): string
{
return $this->embedWithVariables($path, []);
}

public function embedWithVariables(string $path, array $variables): string
{
$script = self::minify($path);
if (count($variables) === 0) {
return $script;
}

$declaredVariables = array_reduce(array_keys($variables),
fn ($vars, $key) => $vars . PHP_EOL . sprintf('var %s = %s;', $key,
json_encode($variables[$key], JSON_PRETTY_PRINT)), '');

return trim($declaredVariables . PHP_EOL . $script);
}

private static function minify(string ...$paths): string
{
$minifier = new JSMinify(array_map([self::class, 'resolvePath'], $paths));

return $minifier->minify();
}

/**
* Resolve resource:// to absolute uris as the minifier does not "uri like" paths
*/
private static function resolvePath(string $path): string
{
if (strpos($path, 'resource://') !== 0) {
return $path;
}

$streamWrapper = Bootstrap::$staticObjectManager->get(ResourceStreamWrapper::class);
$reflectionClass = new ReflectionClass($streamWrapper);

$method = $reflectionClass->getMethod('evaluateResourcePath');
$method->setAccessible(true);

return $method->invoke($streamWrapper, $path);
}

public function allowsCallOfMethod($methodName): bool
{
return true;
}
}
4 changes: 4 additions & 0 deletions Configuration/Settings.Fusion.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Neos:
Fusion:
defaultContext:
'Netlogix.JavaScript': 'Netlogix\Eel\JavaScript\Helper\JavaScriptHelper'
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2024 netlogix GmbH & Co. KG

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
30 changes: 30 additions & 0 deletions Tests/Fixtures/bubblesort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Bubble sort Implementation using JavaScript
// https://www.geeksforgeeks.org/bubble-sort-algorithms-by-using-javascript/

// Creating the bblSort function
function bblSort(arr) {

for (var i = 0; i < arr.length; i++) {

// Last i elements are already in place
for (var j = 0; j < (arr.length - i - 1); j++) {

// Checking if the item at present iteration
// is greater than the next iteration
if (arr[j] > arr[j + 1]) {

// If the condition is true
// then swap them
var temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}

// Print the sorted array
console.log(arr);
}

// Now pass this array to the bblSort() function
bblSort(arr);
1 change: 1 addition & 0 deletions Tests/Fixtures/hello-world.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('Hello World');
118 changes: 118 additions & 0 deletions Tests/Unit/Helper/JavaScriptHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

declare(strict_types=1);

namespace Netlogix\Eel\JavaScript\Tests\Unit\Helper;

use Neos\Flow\Core\Bootstrap;
use Neos\Flow\ObjectManagement\ObjectManagerInterface;
use Neos\Flow\ResourceManagement\Streams\ResourceStreamWrapper;
use Neos\Flow\Tests\UnitTestCase;
use Netlogix\Eel\JavaScript\Helper\JavaScriptHelper;

class JavaScriptHelperTest extends UnitTestCase
{
/**
* @test
*/
public function testEmbed(): void
{
$fileName = __DIR__ . '/../../Fixtures/hello-world.js';

$helper = new JavaScriptHelper();

$this->assertEquals(
<<<JS
console.log('Hello World')
JS,
$helper->embed($fileName)
);
}

/**
* @test
*/
public function testEmbedWithVariables(): void
{
$fileName = __DIR__ . '/../../Fixtures/hello-world.js';

$helper = new JavaScriptHelper();

$this->assertEquals(
<<<JS
var someGreatVariable = "withSomeValue";
var andAnInt = 42;
console.log('Hello World')
JS,
$helper->embedWithVariables($fileName, ['someGreatVariable' => 'withSomeValue', 'andAnInt' => 42])
);
}

/**
* @test
*/
public function testCodeIsMinified(): void
{
$fileName = __DIR__ . '/../../Fixtures/bubblesort.js';

$helper = new JavaScriptHelper();

$this->assertEquals(
<<<JS
var arr = [
234,
43,
55,
63,
5,
6,
235,
547
];
function bblSort(arr){for(var i=0;i<arr.length;i++){for(var j=0;j<(arr.length-i-1);j++){if(arr[j]>arr[j+1]){var temp=arr[j]
arr[j]=arr[j+1]
arr[j+1]=temp}}}
console.log(arr)}
bblSort(arr)
JS,
$helper->embedWithVariables($fileName, ['arr' => [234, 43, 55, 63, 5, 6, 235, 547]])
);
}

/**
* @test
*/
public function Flow_resource_Uris_are_resolved(): void
{
$fileName = 'resource://Netlogix.Eel.JavaScript/Private/JavaScript/hello-world.js';
$previousStaticObjectManager = Bootstrap::$staticObjectManager;
try {
$objectManager = $this->getMockBuilder(ObjectManagerInterface::class)->getMock();
$streamWrapper = new class extends ResourceStreamWrapper {
protected function evaluateResourcePath($requestedPath, $checkForExistence = true)
{
return __DIR__ . '/../../Fixtures/hello-world.js';
}
};

$objectManager
->expects(self::once())
->method('get')
->with(ResourceStreamWrapper::class)
->willReturn($streamWrapper);

Bootstrap::$staticObjectManager = $objectManager;

$helper = new JavaScriptHelper();

$this->assertEquals(
<<<JS
console.log('Hello World')
JS,
$helper->embed($fileName)
);
} finally {
Bootstrap::$staticObjectManager = $previousStaticObjectManager;
}
}
}
19 changes: 19 additions & 0 deletions Tests/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" beStrictAboutChangesToGlobalState="true"
beStrictAboutOutputDuringTests="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true"
convertWarningsToExceptions="true" timeoutForSmallTests="0"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<testsuites>
<testsuite name="Unit">
<directory>./Unit/</directory>
</testsuite>
</testsuites>
<logging>
<junit outputFile="Build/Artifacts/Reports/PhpUnit/junit.xml"/>
</logging>
<php>
<ini name="date.timezone" value="Europe/Berlin"/>
<ini name="error_reporting" value="E_ALL &amp; ~E_DEPRECATED"/>
<env name="FLOW_REWRITEURLS" value="1"/>
</php>
</phpunit>
22 changes: 22 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "netlogix/eel-javascript",
"description": "Neos Eel Helper to embed inline JavaScript",
"type": "neos-package",
"license": "MIT",
"require": {
"neos/eel": "^7.3 || ^8.3",
"neos/flow": "^7.3 || ^8.3",
"neos/fusion": "^7.3 || ^8.3",
"matthiasmullie/minify": "^1.3"
},
"autoload": {
"psr-4": {
"Netlogix\\Eel\\JavaScript\\": "Classes/"
}
},
"extra": {
"neos": {
"package-key": "Netlogix.Eel.JavaScript"
}
}
}

0 comments on commit d224d94

Please sign in to comment.