Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop:
  add mention to the fix of ::prependChild()
  specify next release
  add AsContent interface to dump nodes as file content
  fix possible negative value
  CS
  avoid unwrapping children sequence when prepending a node
  • Loading branch information
Baptouuuu committed Nov 26, 2022
2 parents c53ae8a + 8df2a57 commit b9396d8
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 46 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changelog

## 7.1.0 - 2022-11-26

### Added

- `Innmind\Xml\AsContent` interface implemented on `Innmind\Xml\Node\Document` and `Innmind\Xml\Element\Element`

### Fixed

- Calling `prependChild` on `Node\Document` and `Element\Element` won't unwrap all the children in memory in case of a lazy sequence
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"require": {
"php": "~8.1",
"innmind/immutable": "~4.2",
"innmind/immutable": "^4.7.1",
"innmind/filesystem": "~5.1"
},
"autoload": {
Expand Down
11 changes: 11 additions & 0 deletions src/AsContent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
declare(strict_types = 1);

namespace Innmind\Xml;

use Innmind\Filesystem\File\Content;

interface AsContent
{
public function asContent(): Content;
}
52 changes: 44 additions & 8 deletions src/Element/Element.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
Element as ElementInterface,
Attribute,
Node,
AsContent,
Exception\DomainException,
};
use Innmind\Filesystem\File\Content;
use Innmind\Immutable\{
Map,
Sequence,
Expand All @@ -20,7 +22,7 @@
/**
* @psalm-immutable
*/
final class Element implements ElementInterface
final class Element implements ElementInterface, AsContent
{
/** @var non-empty-string */
private string $name;
Expand Down Expand Up @@ -165,10 +167,7 @@ public function mapChild(callable $map): self
public function prependChild(Node $child): self
{
$element = clone $this;
$element->children = Sequence::of(
$child,
...$this->children->toList(),
);
$element->children = Sequence::lazyStartingWith($child)->append($this->children);

return $element;
}
Expand All @@ -191,6 +190,37 @@ public function content(): string
}

public function toString(): string
{
return \sprintf(
'%s%s%s',
$this->openingTag(),
$this->content(),
$this->closingTag(),
);
}

public function asContent(): Content
{
return Content\Lines::of(
Sequence::lazyStartingWith(Content\Line::of(Str::of($this->openingTag())))
->append(
$this
->children
->flatMap(
static fn($node) => match ($node instanceof AsContent) {
true => $node->asContent()->lines(),
false => Content\Lines::ofContent($node->toString())->lines(),
},
)
->map(static fn($line) => $line->map(
static fn($string) => $string->prepend(' '), // to correctly indent the file
)),
)
->add(Content\Line::of(Str::of($this->closingTag()))),
);
}

private function openingTag(): string
{
$attributes = $this
->attributes
Expand All @@ -200,10 +230,16 @@ public function toString(): string
);

return \sprintf(
'<%s%s>%s</%s>',
'<%s%s>',
$this->name(),
!$this->attributes()->empty() ? ' '.Str::of(' ')->join($attributes)->toString() : '',
$this->content(),
!$attributes->empty() ? ' '.Str::of(' ')->join($attributes)->toString() : '',
);
}

private function closingTag(): string
{
return \sprintf(
'</%s>',
$this->name(),
);
}
Expand Down
49 changes: 36 additions & 13 deletions src/Node/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
Node\Document\Type,
Node\Document\Version,
Node\Document\Encoding,
AsContent,
};
use Innmind\Filesystem\File\Content;
use Innmind\Immutable\{
Sequence,
Str,
Expand All @@ -18,7 +20,7 @@
/**
* @psalm-immutable
*/
final class Document implements Node
final class Document implements Node, AsContent
{
private Version $version;
/** @var Maybe<Type> */
Expand Down Expand Up @@ -102,10 +104,7 @@ public function mapChild(callable $map): self
public function prependChild(Node $child): Node
{
$document = clone $this;
$document->children = Sequence::of(
$child,
...$this->children->toList(),
);
$document->children = Sequence::lazyStartingWith($child)->append($this->children);

return $document;
}
Expand Down Expand Up @@ -137,7 +136,38 @@ public function content(): string

public function toString(): string
{
$string = \sprintf(
$string = $this->tag();

$string .= $this->type->match(
static fn($type) => "\n".$type->toString(),
static fn() => '',
);

return $string."\n".$this->content();
}

public function asContent(): Content
{
return Content\Lines::of(
Sequence::lazyStartingWith(Content\Line::of(Str::of($this->tag())))
->append($this->type->match(
static fn($type) => Sequence::of(Content\Line::of(Str::of($type->toString()))),
static fn() => Sequence::of(),
))
->append(
$this
->children
->flatMap(static fn($node) => match ($node instanceof AsContent) {
true => $node->asContent()->lines(),
false => Content\Lines::ofContent($node->toString())->lines(),
}),
),
);
}

private function tag(): string
{
return \sprintf(
'<?xml version="%s"%s?>',
$this->version->toString(),
$this
Expand All @@ -148,12 +178,5 @@ public function toString(): string
static fn() => '',
),
);

$string .= $this->type->match(
static fn($type) => "\n".$type->toString(),
static fn() => '',
);

return $string."\n".$this->content();
}
}
2 changes: 2 additions & 0 deletions src/Visitor/PreviousSibling.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ public function __invoke(Node $tree): Maybe
static fn($parent) => $parent->children(),
);

/** @psalm-suppress ArgumentTypeCoercion */
return $children
->flatMap(fn($children) => $children->indexOf($this->node))
->filter(static fn($position) => $position >= 0)
->flatMap(static fn($position) => $children->flatMap(
static fn($children) => $children->get($position - 1),
));
Expand Down
32 changes: 32 additions & 0 deletions tests/Element/ElementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
Element\Element,
Node,
Attribute,
AsContent,
Exception\DomainException,
};
use Innmind\Immutable\{
Expand All @@ -30,6 +31,10 @@ public function testInterface()
Node::class,
Element::of('foo'),
);
$this->assertInstanceOf(
AsContent::class,
Element::of('foo'),
);
}

public function testName()
Expand Down Expand Up @@ -411,4 +416,31 @@ public function testMapChild()
$this->assertTrue($element2->children()->contains($replacement));
});
}

public function testAsContent()
{
$element = Element::of(
'foo',
Set::of(
Attribute::of('bar', 'baz'),
Attribute::of('baz', 'foo'),
),
Sequence::of(
Element::of('bar'),
Element::of('baz'),
),
);

$this->assertSame(
<<<CONTENT
<foo bar="baz" baz="foo">
<bar>
</bar>
<baz>
</baz>
</foo>
CONTENT,
$element->asContent()->toString(),
);
}
}
41 changes: 41 additions & 0 deletions tests/Node/DocumentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Node,
Element\Element,
Element\SelfClosingElement,
AsContent,
};
use Innmind\Immutable\{
Map,
Expand All @@ -33,6 +34,10 @@ public function testInterface()
Node::class,
Document::of(Version::of(1), Maybe::nothing(), Maybe::nothing()),
);
$this->assertInstanceOf(
AsContent::class,
Document::of(Version::of(1), Maybe::nothing(), Maybe::nothing()),
);
}

public function testVersion()
Expand Down Expand Up @@ -303,4 +308,40 @@ public function testMapChild()
$this->assertTrue($element2->children()->contains($replacement));
});
}

public function testAsContent()
{
$document = Document::of(
Version::of(1),
Maybe::just(Type::of('html')),
Maybe::just(Encoding::of('utf-8')),
Sequence::of(
Element::of(
'root',
null,
Sequence::of(
Element::of('foo'),
Element::of('bar'),
Element::of('baz'),
),
),
),
);

$this->assertSame(
<<<CONTENT
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<root>
<foo>
</foo>
<bar>
</bar>
<baz>
</baz>
</root>
CONTENT,
$document->asContent()->toString(),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ public function testReturnNothingWhenInvalidNode()
$this->assertNull(CharacterDataTranslator::of()(
new \DOMNode,
Translator::of(Map::of()),
)->match(
static fn($node) => $node,
static fn() => null,
));
)->match(
static fn($node) => $node,
static fn() => null,
));
}
}
8 changes: 4 additions & 4 deletions tests/Translator/NodeTranslator/CommentTranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ public function testReturnNothingWhenInvalidNode()
$this->assertNull(CommentTranslator::of()(
new \DOMNode,
Translator::of(Map::of()),
)->match(
static fn($node) => $node,
static fn() => null,
));
)->match(
static fn($node) => $node,
static fn() => null,
));
}
}
8 changes: 4 additions & 4 deletions tests/Translator/NodeTranslator/DocumentTranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ public function testReturnNothingWhenInvalidNode()
$this->assertNull(DocumentTranslator::of()(
new \DOMNode,
Translator::of(Map::of()),
)->match(
static fn($node) => $node,
static fn() => null,
));
)->match(
static fn($node) => $node,
static fn() => null,
));
}
}
8 changes: 4 additions & 4 deletions tests/Translator/NodeTranslator/ElementTranslatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ public function testReturnNothingWhenInvalidNode()
$this->assertNull(ElementTranslator::of()(
new \DOMNode,
Translator::of(Map::of()),
)->match(
static fn($node) => $node,
static fn() => null,
));
)->match(
static fn($node) => $node,
static fn() => null,
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public function testReturnNothingWhenInvalidNode()
$this->assertNull(EntityReferenceTranslator::of()(
new \DOMNode,
Translator::of(Map::of()),
)->match(
static fn($node) => $node,
static fn() => null,
));
)->match(
static fn($node) => $node,
static fn() => null,
));
}
}
Loading

0 comments on commit b9396d8

Please sign in to comment.