Skip to content

Commit 212ea63

Browse files
committed
#157 WIP
1 parent 485cee7 commit 212ea63

10 files changed

+119
-52
lines changed

api/src/Markdown/Extractor/DOMExtractor.php

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,32 @@
77

88
class DOMExtractor
99
{
10-
/** @var DOMNode[] **/
10+
/** @var DOMNode[] * */
1111
private array $question = [];
12-
/** @var DOMNode[] **/
12+
/** @var DOMNode[] * */
1313
private array $possibleAnswers = [];
14-
/** @var DOMNode[] **/
14+
/** @var DOMNode[] * */
1515
private array $correctAnswer = [];
1616

1717
private bool $foundPossibleAnswers = false;
1818
private bool $foundCorrectAnswer = false;
1919

20-
public function __construct(private readonly string $document)
21-
{
22-
}
23-
2420
/**
25-
* @return void
21+
* @return array{question: DOMNode[], possible_answers: DOMNode[], correct_answer:DOMNode[] }
2622
*/
27-
public function extract(): void
23+
public function extract(string $document): array
2824
{
2925
$domDocument = new DOMDocument();
3026
libxml_use_internal_errors(true);
31-
$domDocument->loadHTML($this->document);
27+
$domDocument->loadHTML($document);
3228

3329
$this->process($domDocument);
30+
31+
return [
32+
'question' => $this->question,
33+
'possible_answers' => $this->possibleAnswers,
34+
'correct_answer' => $this->correctAnswer
35+
];
3436
}
3537

3638
public function process(DOMNode $domNode): void
@@ -72,19 +74,19 @@ public function process(DOMNode $domNode): void
7274
}
7375
}
7476

75-
/** @return DOMNode[] **/
77+
/** @return DOMNode[] * */
7678
public function getQuestionNodes(): array
7779
{
7880
return $this->question;
7981
}
8082

81-
/** @return DOMNode[] **/
83+
/** @return DOMNode[] * */
8284
public function getPossibleAnswerNodes(): array
8385
{
8486
return $this->possibleAnswers;
8587
}
8688

87-
/** @return DOMNode[] **/
89+
/** @return DOMNode[] * */
8890
public function getCorrectAnswerNodes(): array
8991
{
9092
return $this->correctAnswer;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace App\Markdown\Parser;
4+
5+
use App\Markdown\Extractor\DOMExtractor;
6+
use App\Markdown\Model\Question;
7+
use Parsedown;
8+
9+
class MarkdownParser
10+
{
11+
public function __construct(private readonly Parsedown $parsedown, private readonly DOMExtractor $DOMExtractor)
12+
{
13+
}
14+
15+
16+
public function parser(Question $question): Question
17+
{
18+
$filePath = $question->getFilePath();
19+
$markdown = file_get_contents($filePath);
20+
21+
$html = $this->parsedown->parse($markdown);
22+
23+
$parts = $this->DOMExtractor->extract($html);
24+
25+
$question->setContent($parts['question'])
26+
->setCorrectAnswer($parts['correct_answer'])
27+
->setPossibleAnswers($parts['possible_answers']);
28+
return $question;
29+
}
30+
}

api/src/Markdown/QuestionGenerator.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
namespace App\Markdown;
44

55
use App\Markdown\Model\Question;
6+
use App\Markdown\Parser\MarkdownParser;
67

78
class QuestionGenerator implements GeneratorInterface
89
{
9-
public function __construct(private readonly FetcherInterface $fetcher)
10+
public function __construct(private readonly FetcherInterface $fetcher, private readonly MarkdownParser $markdownParser)
1011
{
1112
}
1213

@@ -74,6 +75,7 @@ public function process(array $filePaths): array
7475
}
7576

7677
$question = new Question($questionID, $quizID, $filePath, $title);
78+
$question = $this->markdownParser->parser($question);
7779

7880
$dataSets[] = $question;
7981
}

api/tests/unit/src/Markdown/Extractor/CorrectAnswerExtractorTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ public function setUp(): void
1818

1919
public function testAnswerElement()
2020
{
21-
$parser = new DOMExtractor($this->document);
22-
$parser->extract();
21+
$parser = new DOMExtractor();
22+
$parser->extract($this->document);
2323
$questionNodes = $parser->getCorrectAnswerNodes();
2424

2525
self::assertSame('p', $questionNodes[4]->nodeName);
2626
}
2727

2828
public function testAnswerValue()
2929
{
30-
$parser = new DOMExtractor($this->document);
31-
$parser->extract();
30+
$parser = new DOMExtractor();
31+
$parser->extract($this->document);
3232
$questionNodes = $parser->getCorrectAnswerNodes();
3333

3434
self::assertSame('Answer: 5', trim($questionNodes[4]->nodeValue));

api/tests/unit/src/Markdown/Extractor/PossibleAnswerExtractorTest.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,35 @@ public function setUp(): void
1818

1919
public function testHeadingValue()
2020
{
21-
$parser = new DOMExtractor($this->document);
22-
$parser->extract();
21+
$parser = new DOMExtractor();
22+
$parser->extract($this->document);
2323
$nodes = $parser->getPossibleAnswerNodes();
2424

2525
self::assertSame('Possible answers', $nodes[0]->nodeValue);
2626
}
2727

2828
public function testHeadingElement()
2929
{
30-
$parser = new DOMExtractor($this->document);
31-
$parser->extract();
30+
$parser = new DOMExtractor();
31+
$parser->extract($this->document);
3232
$nodes = $parser->getPossibleAnswerNodes();
3333

3434
self::assertSame('h2', $nodes[0]->nodeName);
3535
}
3636

3737
public function testFirstPossibleAnswerValue()
3838
{
39-
$parser = new DOMExtractor($this->document);
40-
$parser->extract();
39+
$parser = new DOMExtractor();
40+
$parser->extract($this->document);
4141
$nodes = $parser->getPossibleAnswerNodes();
4242

4343
self::assertSame('[ ] 3', $nodes[2]->nodeValue);
4444
}
4545

4646
public function testFirstPossibleAnswerElement()
4747
{
48-
$parser = new DOMExtractor($this->document);
49-
$parser->extract();
48+
$parser = new DOMExtractor();
49+
$parser->extract($this->document);
5050
$nodes = $parser->getPossibleAnswerNodes();
5151

5252
self::assertSame('li', $nodes[2]->nodeName);
@@ -55,8 +55,8 @@ public function testFirstPossibleAnswerElement()
5555

5656
public function testLastPossibleAnswerValue()
5757
{
58-
$parser = new DOMExtractor($this->document);
59-
$parser->extract();
58+
$parser = new DOMExtractor();
59+
$parser->extract($this->document);
6060
$nodes = $parser->getPossibleAnswerNodes();
6161
$lastIndex = count($nodes) - 1;
6262

@@ -65,8 +65,8 @@ public function testLastPossibleAnswerValue()
6565

6666
public function testLastPossibleAnswerElement()
6767
{
68-
$parser = new DOMExtractor($this->document);
69-
$parser->extract();
68+
$parser = new DOMExtractor();
69+
$parser->extract($this->document);
7070
$nodes = $parser->getPossibleAnswerNodes();
7171
$lastIndex = count($nodes) - 1;
7272

api/tests/unit/src/Markdown/Extractor/QuestionExtractorTest.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,26 @@ public function setUp(): void
1919

2020
public function testQuestionHeadingValue()
2121
{
22-
$parser = new DOMExtractor($this->document);
23-
$parser->extract();
22+
$parser = new DOMExtractor();
23+
$parser->extract($this->document);
2424
$questionNodes = $parser->getQuestionNodes();
2525

2626
self::assertSame('This is the question', $questionNodes[0]->nodeValue);
2727
}
2828

2929
public function testQuestionHeadingElement()
3030
{
31-
$parser = new DOMExtractor($this->document);
32-
$parser->extract();
31+
$parser = new DOMExtractor();
32+
$parser->extract($this->document);
3333
$questionNodes = $parser->getQuestionNodes();
3434

3535
self::assertSame('h1', $questionNodes[0]->nodeName);
3636
}
3737

3838
public function testLastQuestionElement()
3939
{
40-
$parser = new DOMExtractor($this->document);
41-
$parser->extract();
40+
$parser = new DOMExtractor();
41+
$parser->extract($this->document);
4242
$questionNodes = $parser->getQuestionNodes();
4343
$count = count($questionNodes) - 1;
4444

@@ -47,8 +47,8 @@ public function testLastQuestionElement()
4747

4848
public function testLastQuestionValue()
4949
{
50-
$parser = new DOMExtractor($this->document);
51-
$parser->extract();
50+
$parser = new DOMExtractor();
51+
$parser->extract($this->document);
5252
$questionNodes = $parser->getQuestionNodes();
5353
$count = count($questionNodes) - 1;
5454

api/tests/unit/src/Markdown/QuestionGeneratorTest.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace App\Tests\unit\src\Markdown;
44

55
use App\Markdown\FetcherInterface;
6+
use App\Markdown\Model\Question;
7+
use App\Markdown\Parser\MarkdownParser;
68
use App\Markdown\QuestionFetcher;
79
use App\Markdown\QuizFetcher;
810
use App\Markdown\QuestionGenerator;
@@ -31,7 +33,13 @@ public function setUp(): void
3133

3234
public function testGeneratedQuestionID()
3335
{
34-
$quizGenerator = new QuestionGenerator($this->fetcherMock);
36+
$question = $this->createMock(Question::class);
37+
$question->expects(self::once())->method('getId')->willReturn(2);
38+
39+
$parserMock = $this->createMock(MarkdownParser::class);
40+
$parserMock->expects(self::any())->method('parser')->willReturn($question);
41+
42+
$quizGenerator = new QuestionGenerator($this->fetcherMock, $parserMock);
3543
$dataSets = $quizGenerator->generate(self::SOURCE);
3644

3745
$question2 = $dataSets[1];
@@ -41,19 +49,30 @@ public function testGeneratedQuestionID()
4149

4250
public function testGeneratedQuizID()
4351
{
44-
$quizGenerator = new QuestionGenerator($this->fetcherMock);
52+
$question = $this->createMock(Question::class);
53+
$question->expects(self::once())->method('getQuizId')->willReturn(1);
54+
55+
$parserMock = $this->createMock(MarkdownParser::class);
56+
$parserMock->expects(self::any())->method('parser')->willReturn($question);
57+
58+
$quizGenerator = new QuestionGenerator($this->fetcherMock, $parserMock);
4559
$dataSets = $quizGenerator->generate(self::SOURCE);
4660

4761
$question2 = $dataSets[1];
4862

4963
self::assertSame(1, $question2->getQuizId());
50-
self::assertSame('Style override', $question2->getTitle());
5164
}
5265

5366

5467
public function testGeneratedTitle()
5568
{
56-
$quizGenerator = new QuestionGenerator($this->fetcherMock);
69+
$question = $this->createMock(Question::class);
70+
$question->expects(self::once())->method('getTitle')->willReturn('Style override');
71+
72+
$parserMock = $this->createMock(MarkdownParser::class);
73+
$parserMock->expects(self::any())->method('parser')->willReturn($question);
74+
75+
$quizGenerator = new QuestionGenerator($this->fetcherMock, $parserMock);
5776
$dataSets = $quizGenerator->generate(self::SOURCE);
5877

5978
$question2 = $dataSets[1];

api/tests/unit/src/Markdown/QuestionIDGeneratorTest.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Tests\unit\src\Markdown;
44

55
use App\Markdown\FetcherInterface;
6+
use App\Markdown\Parser\MarkdownParser;
67
use App\Markdown\QuestionGenerator;
78
use PHPUnit\Framework\TestCase;
89

@@ -11,31 +12,36 @@ class QuestionIDGeneratorTest extends TestCase
1112
public function testGetQuestionID()
1213
{
1314
$fetcherMock = $this->createMock(FetcherInterface::class);
14-
$generator = new QuestionGenerator($fetcherMock);
15+
$parserMock = $this->createMock(MarkdownParser::class);
16+
$generator = new QuestionGenerator($fetcherMock, $parserMock);
1517
$questionID = $generator->getIDFromFilePath('1_2_style_override.md', false);
1618
self::assertSame(2, $questionID);
1719
}
1820

1921
public function testGetQuestionIDWithDoubleDigits()
2022
{
2123
$fetcherMock = $this->createMock(FetcherInterface::class);
22-
$generator = new QuestionGenerator($fetcherMock);
24+
$parserMock = $this->createMock(MarkdownParser::class);
25+
$generator = new QuestionGenerator($fetcherMock, $parserMock);
2326
$questionID = $generator->getIDFromFilePath('1_20_style_override.md', false);
2427
self::assertSame(20, $questionID);
2528
}
2629

2730
public function testGetQuestionIDWithNoIDValue()
2831
{
2932
$fetcherMock = $this->createMock(FetcherInterface::class);
30-
$generator = new QuestionGenerator($fetcherMock);
33+
$parserMock = $this->createMock(MarkdownParser::class);
34+
$generator = new QuestionGenerator($fetcherMock, $parserMock);
3135
$questionID = $generator->getIDFromFilePath('1.md', false);
3236
self::assertFalse($questionID);
3337
}
3438

3539
public function testGetQuestionIDWithIncorrectValueType()
3640
{
3741
$fetcherMock = $this->createMock(FetcherInterface::class);
38-
$generator = new QuestionGenerator($fetcherMock);
42+
$parserMock = $this->createMock(MarkdownParser::class);
43+
$generator = new QuestionGenerator($fetcherMock, $parserMock);
44+
$questionID = $generator->getIDFromFilePath('1_two.md', false);
3945
$questionID = $generator->getIDFromFilePath('1_two.md', false);
4046
self::assertFalse($questionID);
4147
}

0 commit comments

Comments
 (0)