Skip to content
This repository was archived by the owner on Mar 29, 2024. It is now read-only.

Commit ee47f05

Browse files
committed
Add NativeObjectWrapper, closes #2
1 parent ce2b1de commit ee47f05

File tree

8 files changed

+359
-54
lines changed

8 files changed

+359
-54
lines changed

src/Modules/ModulesService.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function createNativeFunctionWrapper(Context $context, RequireCallbackInt
6565
$runtime_function = $this->createRuntimeFunction($require_object);
6666
$function_object = $this->createFunctionObject($context, $runtime_function, $wrapper);
6767

68-
return new NativeRequireFunctionWrapper($context, $context->globalObject(), $function_object, $wrapper);
68+
return new NativeRequireFunctionWrapper($context->getIsolate(), $context, $function_object, $wrapper, $context->globalObject());
6969
}
7070

7171
/**

src/NativeWrappers/NativeFunctionWrapper.php

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,54 +19,36 @@
1919
use Pinepain\JsSandbox\Wrappers\WrapperInterface;
2020
use V8\Context;
2121
use V8\FunctionObject;
22+
use V8\Isolate;
2223
use V8\ObjectValue;
24+
use V8\Value;
2325

2426

25-
class NativeFunctionWrapper implements NativeFunctionWrapperInterface
27+
class NativeFunctionWrapper extends NativeObjectWrapper implements NativeFunctionWrapperInterface
2628
{
27-
/**
28-
* @var Context
29-
*/
30-
private $context;
3129
/**
3230
* @var ObjectValue
3331
*/
34-
private $recv;
35-
/**
36-
* @var FunctionObject
37-
*/
38-
private $function_object;
39-
/**
40-
* @var WrapperInterface
41-
*/
42-
private $wrapper;
32+
protected $recv;
4333

44-
public function __construct(Context $context, ObjectValue $recv, FunctionObject $function_object, WrapperInterface $wrapper)
34+
public function __construct(Isolate $isolate, Context $context, FunctionObject $target, WrapperInterface $wrapper, ObjectValue $recv)
4535
{
46-
$this->context = $context;
47-
$this->recv = $recv;
48-
$this->function_object = $function_object;
49-
$this->wrapper = $wrapper;
36+
parent::__construct($isolate, $context, $target, $wrapper);
37+
$this->recv = $recv;
5038
}
5139

5240
/**
5341
* {@inheritdoc}
5442
*/
55-
public function call(...$args)
43+
public function call(...$args): Value
5644
{
5745
$args_for_call = [];
5846
foreach ($args as $arg) {
5947
$args_for_call[] = $this->wrapper->wrap($this->context->getIsolate(), $this->context, $arg);
6048
}
6149

62-
return $this->function_object->call($this->context, $this->recv, $args_for_call);
63-
}
50+
assert($this->target instanceof FunctionObject);
6451

65-
/**
66-
* {@inheritdoc}
67-
*/
68-
public function __invoke(...$args)
69-
{
70-
return $this->call(... $args);
52+
return $this->target->call($this->context, $this->recv, $args_for_call);
7153
}
7254
}

src/NativeWrappers/NativeFunctionWrapperInterface.php

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,12 @@
1919
use V8\Value;
2020

2121

22-
interface NativeFunctionWrapperInterface
22+
interface NativeFunctionWrapperInterface extends NativeObjectWrapperInterface
2323
{
2424
/**
2525
* @param array ...$args
2626
*
2727
* @return Value
2828
*/
29-
public function call(...$args);
30-
31-
/**
32-
* @param array ...$args
33-
*
34-
* @return Value
35-
*/
36-
public function __invoke(...$args);
29+
public function call(...$args): Value;
3730
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of the pinepain/js-sandbox PHP library.
5+
*
6+
* Copyright (c) 2016-2017 Bogdan Padalko <pinepain@gmail.com>
7+
*
8+
* Licensed under the MIT license: http://opensource.org/licenses/MIT
9+
*
10+
* For the full copyright and license information, please view the
11+
* LICENSE file that was distributed with this source or visit
12+
* http://opensource.org/licenses/MIT
13+
*/
14+
15+
16+
namespace Pinepain\JsSandbox\NativeWrappers;
17+
18+
19+
use Pinepain\JsSandbox\Wrappers\WrapperInterface;
20+
use V8\Context;
21+
use V8\FunctionObject;
22+
use V8\Isolate;
23+
use V8\ObjectValue;
24+
use V8\StringValue;
25+
use V8\Value;
26+
27+
28+
class NativeObjectWrapper implements NativeObjectWrapperInterface
29+
{
30+
/**
31+
* @var Isolate
32+
*/
33+
protected $isolate;
34+
/**
35+
* @var Context
36+
*/
37+
protected $context;
38+
/**
39+
* @var ObjectValue|FunctionObject
40+
*/
41+
protected $target;
42+
/**
43+
* @var WrapperInterface
44+
*/
45+
protected $wrapper;
46+
47+
/**
48+
* @inheritDoc
49+
*/
50+
public function __construct(Isolate $isolate, Context $context, ObjectValue $target, WrapperInterface $wrapper)
51+
{
52+
$this->isolate = $isolate;
53+
$this->context = $context;
54+
$this->target = $target;
55+
$this->wrapper = $wrapper;
56+
}
57+
58+
/**
59+
* {@inheritdoc}
60+
*/
61+
public function set(string $key, $value): void
62+
{
63+
$wrapped_key = $this->wrapKey($key);
64+
$wrapped_value = $this->wrapper->wrap($this->isolate, $this->context, $value);
65+
66+
$this->target->set($this->context, $wrapped_key, $wrapped_value);
67+
}
68+
69+
/**
70+
* {@inheritdoc}
71+
*/
72+
public function get(string $key): Value
73+
{
74+
$wrapped_key = $this->wrapKey($key);
75+
76+
$value = $this->target->get($this->context, $wrapped_key);
77+
78+
// TODO: could we extract PHP value from the native v8 value?
79+
return $value;
80+
}
81+
82+
/**
83+
* {@inheritdoc}
84+
*/
85+
public function has(string $key): bool
86+
{
87+
$wrapped_key = $this->wrapKey($key);
88+
89+
return $this->target->has($this->context, $wrapped_key);
90+
}
91+
92+
/**
93+
* {@inheritdoc}
94+
*/
95+
public function delete(string $key): bool
96+
{
97+
$wrapped_key = $this->wrapKey($key);
98+
99+
return $this->target->delete($this->context, $wrapped_key);
100+
}
101+
102+
protected function wrapKey(string $key): StringValue
103+
{
104+
return new StringValue($this->isolate, $key);
105+
}
106+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of the pinepain/js-sandbox PHP library.
5+
*
6+
* Copyright (c) 2016-2017 Bogdan Padalko <pinepain@gmail.com>
7+
*
8+
* Licensed under the MIT license: http://opensource.org/licenses/MIT
9+
*
10+
* For the full copyright and license information, please view the
11+
* LICENSE file that was distributed with this source or visit
12+
* http://opensource.org/licenses/MIT
13+
*/
14+
15+
16+
namespace Pinepain\JsSandbox\NativeWrappers;
17+
18+
19+
use V8\ObjectValue;
20+
use V8\PrimitiveValue;
21+
use V8\Value;
22+
23+
24+
interface NativeObjectWrapperInterface
25+
{
26+
/**
27+
* @param string $key
28+
* @param mixed $value
29+
*/
30+
public function set(string $key, $value): void;
31+
32+
/**
33+
*
34+
* @param string $key
35+
*
36+
* @return Value|PrimitiveValue|ObjectValue
37+
*/
38+
public function get(string $key): Value;
39+
40+
/**
41+
* @param string $key
42+
*
43+
* @return bool
44+
*/
45+
public function has(string $key): bool;
46+
47+
/**
48+
*
49+
* @param string $key
50+
*
51+
* @return bool
52+
*/
53+
public function delete(string $key): bool;
54+
}

tests/FooTest.php

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of the pinepain/js-sandbox PHP library.
5+
*
6+
* Copyright (c) 2016-2017 Bogdan Padalko <pinepain@gmail.com>
7+
*
8+
* Licensed under the MIT license: http://opensource.org/licenses/MIT
9+
*
10+
* For the full copyright and license information, please view the
11+
* LICENSE file that was distributed with this source or visit
12+
* http://opensource.org/licenses/MIT
13+
*/
14+
15+
16+
namespace Pinepain\JsSandbox\Tests\NativeWrappers;
17+
18+
19+
use PHPUnit\Framework\TestCase;
20+
use PHPUnit_Framework_MockObject_MockObject;
21+
use Pinepain\JsSandbox\NativeWrappers\NativeFunctionWrapper;
22+
use Pinepain\JsSandbox\Wrappers\WrapperInterface;
23+
use V8\Context;
24+
use V8\FunctionCallbackInfo;
25+
use V8\FunctionObject;
26+
use V8\Isolate;
27+
use V8\ObjectValue;
28+
use V8\RegExpObject;
29+
use V8\StringValue;
30+
31+
32+
class NativeFunctionWrapperTest extends TestCase
33+
{
34+
/**
35+
* @var Isolate
36+
*/
37+
private $isolate;
38+
/**
39+
* @var Context
40+
*/
41+
private $context;
42+
/**
43+
* @var FunctionObject
44+
*/
45+
private $target;
46+
/**
47+
* @var WrapperInterface|PHPUnit_Framework_MockObject_MockObject
48+
*/
49+
private $wrapper;
50+
/**
51+
* @var ObjectValue
52+
*/
53+
private $recv;
54+
/**
55+
* @var int
56+
*/
57+
private $invoked;
58+
59+
/**
60+
* @inheritDoc
61+
*/
62+
protected function setUp()
63+
{
64+
$this->isolate = new Isolate();
65+
$this->context = new Context($this->isolate);
66+
$this->target = new FunctionObject($this->context, function (FunctionCallbackInfo $args) {
67+
$this->invoked = $args->arguments();
68+
});
69+
70+
$this->wrapper = $this->createPartialMock(WrapperInterface::class, ['wrap']);
71+
$this->recv = $this->context->globalObject();
72+
}
73+
74+
public function testCall()
75+
{
76+
$obj = new NativeFunctionWrapper($this->isolate, $this->context, $this->target, $this->wrapper, $this->recv);
77+
78+
$this->assertNull($this->invoked);
79+
$obj->call();
80+
$this->assertSame([], $this->invoked);
81+
82+
$args = ['foo', 'bar'];
83+
$wrapped = [
84+
new ObjectValue($this->context),
85+
new RegExpObject($this->context, new StringValue($this->isolate, 'foo.+bar')),
86+
];
87+
88+
$this->wrapper->expects($this->exactly(2))
89+
->method('wrap')
90+
->withConsecutive([$this->isolate, $this->context, $args[0]], [$this->isolate, $this->context, $args[1]])
91+
->willReturnOnConsecutiveCalls($wrapped[0], $wrapped[1]);
92+
93+
94+
$obj->call(...$args);
95+
96+
$this->assertSame($wrapped, $this->invoked);
97+
}
98+
}

0 commit comments

Comments
 (0)