Skip to content

Commit 0440e11

Browse files
Better testing and importing
1 parent 658940e commit 0440e11

12 files changed

+213
-35
lines changed

src/Actions/ConnectReferencesAction.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ public function execute(TransformedCollection $collection): ReferenceMap
3838
return;
3939
}
4040

41-
$metadata['references'][] = $reference;
42-
$typeReference->connect($referenceMap->get($reference));
41+
$transformed = $referenceMap->get($reference);
42+
43+
$metadata['references'][] = $transformed;
44+
$typeReference->connect($transformed);
4345
}, [TypeReference::class]);
4446

4547
foreach ($collection as $transformed) {

src/Actions/ResolveModuleImportsAction.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ public function __construct(
2323

2424
public function execute(
2525
Location $location,
26-
ReferenceMap $referenceMap,
2726
): ImportsCollection {
2827
$collection = new ImportsCollection();
2928

@@ -32,9 +31,7 @@ public function execute(
3231
);
3332

3433
foreach ($location->transformed as $transformedItem) {
35-
foreach ($transformedItem->references as $reference) {
36-
$referencedTransformed = $referenceMap->get($reference);
37-
34+
foreach ($transformedItem->references as $referencedTransformed) {
3835
if ($referencedTransformed->location === $location->segments) {
3936
continue;
4037
}
@@ -80,7 +77,7 @@ protected function resolveImportedName(
8077
}
8178

8279
if (! in_array("{$name}Import", $usedNamesInScope)) {
83-
return "{$name}Alt";
80+
return "{$name}Import";
8481
}
8582

8683
$counter = 2;

src/Actions/ResolveRelativePathAction.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,16 @@ public function execute(array $from, array $to): ?string
2626
$relativeSegments[] = '..';
2727
}
2828

29+
$hasSuffixedSegments = false;
30+
2931
for ($i = $commonDepth; $i < count($to); $i++) {
3032
$relativeSegments[] = $to[$i];
33+
34+
$hasSuffixedSegments = true;
3135
}
3236

33-
return implode('/', $relativeSegments);
34-
}
37+
$relativePath = implode('/', $relativeSegments);
38+
39+
return $hasSuffixedSegments ? $relativePath : $relativePath.'/';
40+
}
3541
}

src/Collections/ImportsCollection.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,15 @@ public function getIterator(): Traversable
5959
*/
6060
public function getTypeScriptNodes(): array
6161
{
62-
return array_map(
62+
return array_values(array_map(
6363
fn (ImportLocation $import) => $import->toTypeScriptNode(),
6464
$this->imports,
65-
);
65+
));
66+
}
67+
68+
/** @return array<ImportLocation> */
69+
public function toArray(): array
70+
{
71+
return array_values($this->imports);
6672
}
6773
}

src/Support/ImportLocation.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ public function toTypeScriptNode(): ?TypeScriptImport
3939
return null;
4040
}
4141

42-
$names = array_unique(array_map(
43-
fn (ImportName $name) => (string) $name,
44-
$this->importNames,
45-
));
46-
47-
return new TypeScriptImport($this->relativePath, $names);
42+
return new TypeScriptImport($this->relativePath, $this->importNames);
4843
}
4944
}

src/Support/Location.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Spatie\TypeScriptTransformer\Support;
44

5+
use Spatie\TypeScriptTransformer\References\Reference;
56
use Spatie\TypeScriptTransformer\Transformed\Transformed;
67

78
class Location
@@ -15,4 +16,20 @@ public function __construct(
1516
public array $transformed,
1617
) {
1718
}
19+
20+
public function getTransformedByReference(Reference $reference): ?Transformed
21+
{
22+
foreach ($this->transformed as $transformed) {
23+
if ($transformed->reference->getKey() === $reference->getKey()) {
24+
return $transformed;
25+
}
26+
}
27+
28+
return null;
29+
}
30+
31+
public function hasReference(Reference $reference): bool
32+
{
33+
return $this->getTransformedByReference($reference) !== null;
34+
}
1835
}

src/Transformed/Transformed.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Transformed
1515

1616
/**
1717
* @param array<string> $location
18-
* @param array<Reference> $references
18+
* @param array<Transformed> $references
1919
*/
2020
public function __construct(
2121
public TypeScriptNode $typeScriptNode,
@@ -26,7 +26,6 @@ public function __construct(
2626
) {
2727
}
2828

29-
3029
public function getName(): ?string
3130
{
3231
if (isset($this->name)) {

src/Writers/ModuleWriter.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,13 @@
33
namespace Spatie\TypeScriptTransformer\Writers;
44

55
use Spatie\TypeScriptTransformer\Actions\ResolveModuleImportsAction;
6-
use Spatie\TypeScriptTransformer\Actions\ResolveRelativePathAction;
76
use Spatie\TypeScriptTransformer\Actions\SplitTransformedPerLocationAction;
87
use Spatie\TypeScriptTransformer\Collections\ReferenceMap;
98
use Spatie\TypeScriptTransformer\References\Reference;
10-
use Spatie\TypeScriptTransformer\Support\ImportName;
119
use Spatie\TypeScriptTransformer\Support\Location;
1210
use Spatie\TypeScriptTransformer\Support\TransformedCollection;
1311
use Spatie\TypeScriptTransformer\Support\WriteableFile;
1412
use Spatie\TypeScriptTransformer\Support\WritingContext;
15-
use Spatie\TypeScriptTransformer\Transformed\Transformed;
16-
use Spatie\TypeScriptTransformer\TypeScript\TypeScriptImport;
1713

1814
class ModuleWriter implements Writer
1915
{
@@ -43,15 +39,12 @@ protected function writeLocation(
4339
Location $location,
4440
ReferenceMap $referenceMap,
4541
): WriteableFile {
46-
$imports = $this->resolveModuleImportsAction->execute(
47-
$location,
48-
$referenceMap,
49-
);
42+
$imports = $this->resolveModuleImportsAction->execute($location);
5043

5144
$output = '';
5245

53-
$writingContext = new WritingContext(function (Reference $reference) use ($referenceMap, $imports) {
54-
if($name = $imports->getAliasOrNameForReference($reference)){
46+
$writingContext = new WritingContext(function (Reference $reference) use ($location, $referenceMap, $imports) {
47+
if ($name = $imports->getAliasOrNameForReference($reference)) {
5548
return $name;
5649
}
5750

@@ -63,7 +56,7 @@ protected function writeLocation(
6356
$output .= $import->write($writingContext);
6457
}
6558

66-
if($imports->isEmpty() === false){
59+
if ($imports->isEmpty() === false) {
6760
$output .= PHP_EOL;
6861
}
6962

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
use Spatie\TypeScriptTransformer\Actions\ResolveModuleImportsAction;
4+
use Spatie\TypeScriptTransformer\Support\ImportLocation;
5+
use Spatie\TypeScriptTransformer\Support\ImportName;
6+
use Spatie\TypeScriptTransformer\Support\Location;
7+
use Spatie\TypeScriptTransformer\Tests\Factories\TransformedFactory;
8+
use Spatie\TypeScriptTransformer\TypeScript\TypeReference;
9+
use Spatie\TypeScriptTransformer\TypeScript\TypeScriptImport;
10+
use Spatie\TypeScriptTransformer\TypeScript\TypeScriptString;
11+
12+
beforeEach(function () {
13+
$this->action = new ResolveModuleImportsAction();
14+
});
15+
16+
it('wont resolve imports when types are in the same module', function () {
17+
$location = new Location([], [
18+
$reference = TransformedFactory::alias('A', new TypeScriptString())->build(),
19+
TransformedFactory::alias('B', new TypeReference($reference->reference), references: [
20+
$reference,
21+
])->build(),
22+
]);
23+
24+
expect($this->action->execute($location)->isEmpty())->toBe(true);
25+
});
26+
27+
it('will import a type from another module', function () {
28+
$nestedReference = TransformedFactory::alias('Nested', new TypeScriptString(), location: ['parent', 'level', 'nested'])->build();
29+
$parentReference = TransformedFactory::alias('Parent', new TypeScriptString(), location: ['parent'])->build();
30+
$deeperParent = TransformedFactory::alias('DeeperParent', new TypeScriptString(), location: ['parent', 'deeper'])->build();
31+
$rootReference = TransformedFactory::alias('Root', new TypeScriptString(), location: [])->build();
32+
33+
$location = new Location(['parent', 'level'], [
34+
TransformedFactory::alias('Type', new TypeScriptString(), references: [
35+
$nestedReference,
36+
$parentReference,
37+
$deeperParent,
38+
$rootReference,
39+
])->build(),
40+
]);
41+
42+
$imports = $this->action->execute($location);
43+
44+
expect($imports->toArray())
45+
->toHaveCount(4)
46+
->each->toBeInstanceOf(ImportLocation::class);
47+
48+
expect($imports->getTypeScriptNodes())->toEqual([
49+
new TypeScriptImport('nested', [new ImportName('Nested', $nestedReference->reference)]),
50+
new TypeScriptImport('../', [new ImportName('Parent', $parentReference->reference)]),
51+
new TypeScriptImport('../deeper', [new ImportName('DeeperParent', $deeperParent->reference)]),
52+
new TypeScriptImport('../../', [new ImportName('Root', $rootReference->reference)]),
53+
]);
54+
});
55+
56+
it('wont import the same type twice', function () {
57+
$nestedReference = TransformedFactory::alias('Nested', new TypeScriptString(), location: ['nested'])->build();
58+
59+
$location = new Location([], [
60+
TransformedFactory::alias('TypeA', new TypeScriptString(), references: [
61+
$nestedReference,
62+
])->build(),
63+
TransformedFactory::alias('TypeB', new TypeScriptString(), references: [
64+
$nestedReference,
65+
])->build(),
66+
]);
67+
68+
$imports = $this->action->execute($location);
69+
70+
expect($imports->toArray())
71+
->toHaveCount(1)
72+
->each->toBeInstanceOf(ImportLocation::class);
73+
74+
expect($imports->getTypeScriptNodes())->toEqual([
75+
new TypeScriptImport('nested', [new ImportName('Nested', $nestedReference->reference)]),
76+
]);
77+
});
78+
79+
it('will alias a reference if it is already in the module', function (){
80+
$nestedCollection = TransformedFactory::alias('Collection', new TypeScriptString(), location: ['nested'])->build();
81+
82+
$location = new Location([], [
83+
TransformedFactory::alias('Collection', new TypeScriptString(), references: [
84+
$nestedCollection,
85+
])->build(),
86+
]);
87+
88+
$imports = $this->action->execute($location);
89+
90+
expect($imports->toArray())
91+
->toHaveCount(1)
92+
->each->toBeInstanceOf(ImportLocation::class);
93+
94+
expect($imports->getTypeScriptNodes())->toEqual([
95+
new TypeScriptImport('nested', [new ImportName('Collection', $nestedCollection->reference, 'CollectionImport')]),
96+
]);
97+
});
98+
99+
it('will alias a reference if it is already in the module and already aliased by another import', function (){
100+
$nestedCollection = TransformedFactory::alias('Collection', new TypeScriptString(), location: ['nested'])->build();
101+
$otherNestedCollection = TransformedFactory::alias('Collection', new TypeScriptString(), location: ['otherNested'])->build();
102+
103+
$location = new Location([], [
104+
TransformedFactory::alias('Collection', new TypeScriptString(), references: [
105+
$nestedCollection,
106+
$otherNestedCollection,
107+
])->build(),
108+
]);
109+
110+
$imports = $this->action->execute($location);
111+
112+
expect($imports->toArray())
113+
->toHaveCount(2)
114+
->each->toBeInstanceOf(ImportLocation::class);
115+
116+
expect($imports->getTypeScriptNodes())->toEqual([
117+
new TypeScriptImport('nested', [new ImportName('Collection', $nestedCollection->reference, 'CollectionImport')]),
118+
new TypeScriptImport('otherNested', [new ImportName('Collection', $otherNestedCollection->reference, 'CollectionImport2')]),
119+
]);
120+
});

tests/Actions/ResolveRelativePathActionTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
['a', 'b', 'c', 'd'],
4444
['a', 'b', 'e', 'd'],
4545
'../../e/d'
46+
],
47+
[
48+
['a', 'b'],
49+
['a'],
50+
'../'
4651
]
4752
]
4853
);

0 commit comments

Comments
 (0)