103 lines
3.2 KiB
PHP
103 lines
3.2 KiB
PHP
<?php
|
|
|
|
use App\Services\CcliPasteParser;
|
|
use App\Services\DTO\ParsedCcliSection;
|
|
use App\Services\DTO\ParsedCcliSong;
|
|
|
|
test('CcliPasteParser can be instantiated with no arguments', function (): void {
|
|
$parser = new CcliPasteParser();
|
|
|
|
expect($parser)->toBeInstanceOf(CcliPasteParser::class);
|
|
});
|
|
|
|
test('CcliPasteParser can be instantiated with closure injections', function (): void {
|
|
$parser = new CcliPasteParser(
|
|
sectionDetector: fn (string $line): bool => str_starts_with($line, 'Verse'),
|
|
metadataDetector: fn (string $line): bool => str_contains($line, '©'),
|
|
);
|
|
|
|
expect($parser)->toBeInstanceOf(CcliPasteParser::class);
|
|
});
|
|
|
|
test('CcliPasteParser resolves from Laravel container', function (): void {
|
|
$parser = app(CcliPasteParser::class);
|
|
|
|
expect($parser)->toBeInstanceOf(CcliPasteParser::class);
|
|
});
|
|
|
|
test('CcliPasteParser::parse returns ParsedCcliSong DTO', function (): void {
|
|
$parser = new CcliPasteParser();
|
|
|
|
$result = $parser->parse("Test Song\nTest Artist\n\nVerse 1\nSome text");
|
|
|
|
expect($result)->toBeInstanceOf(ParsedCcliSong::class);
|
|
});
|
|
|
|
test('ParsedCcliSong DTO has all required properties', function (): void {
|
|
$song = new ParsedCcliSong(
|
|
title: 'Test Song',
|
|
author: 'Test Author',
|
|
ccliId: '9999001',
|
|
year: '2024',
|
|
copyrightText: '© 2024 Test',
|
|
sourceUrl: 'https://songselect.ccli.com/Songs/9999001',
|
|
sections: [],
|
|
);
|
|
|
|
expect($song->title)->toBe('Test Song');
|
|
expect($song->author)->toBe('Test Author');
|
|
expect($song->ccliId)->toBe('9999001');
|
|
expect($song->year)->toBe('2024');
|
|
expect($song->copyrightText)->toBe('© 2024 Test');
|
|
expect($song->sourceUrl)->toContain('songselect.ccli.com');
|
|
expect($song->sections)->toBeArray();
|
|
});
|
|
|
|
test('ParsedCcliSection DTO has all required properties including linesTranslated', function (): void {
|
|
$section = new ParsedCcliSection(
|
|
label: 'Verse 1',
|
|
kind: 'Verse',
|
|
number: '1',
|
|
modifier: null,
|
|
lines: ['Line 1', 'Line 2'],
|
|
linesTranslated: ['Zeile 1', 'Zeile 2'],
|
|
);
|
|
|
|
expect($section->label)->toBe('Verse 1');
|
|
expect($section->kind)->toBe('Verse');
|
|
expect($section->number)->toBe('1');
|
|
expect($section->modifier)->toBeNull();
|
|
expect($section->lines)->toBe(['Line 1', 'Line 2']);
|
|
expect($section->linesTranslated)->toBe(['Zeile 1', 'Zeile 2']);
|
|
});
|
|
|
|
test('ParsedCcliSection linesTranslated defaults to null', function (): void {
|
|
$section = new ParsedCcliSection(
|
|
label: 'Chorus',
|
|
kind: 'Chorus',
|
|
number: null,
|
|
modifier: null,
|
|
lines: ['Line 1'],
|
|
);
|
|
|
|
expect($section->linesTranslated)->toBeNull();
|
|
});
|
|
|
|
test('CcliPasteParser can be injected with closure override in container', function (): void {
|
|
$called = false;
|
|
$fakeParser = new CcliPasteParser(
|
|
sectionDetector: function () use (&$called): bool {
|
|
$called = true;
|
|
|
|
return true;
|
|
},
|
|
);
|
|
|
|
app()->instance(CcliPasteParser::class, $fakeParser);
|
|
$resolved = app(CcliPasteParser::class);
|
|
|
|
expect($resolved)->toBe($fakeParser);
|
|
|
|
app()->forgetInstance(CcliPasteParser::class);
|
|
});
|