Skip to content

Commit

Permalink
#157 WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
pfwd committed Nov 20, 2022
1 parent 485cee7 commit 212ea63
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 52 deletions.
28 changes: 15 additions & 13 deletions api/src/Markdown/Extractor/DOMExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,32 @@

class DOMExtractor
{
/** @var DOMNode[] **/
/** @var DOMNode[] * */
private array $question = [];
/** @var DOMNode[] **/
/** @var DOMNode[] * */
private array $possibleAnswers = [];
/** @var DOMNode[] **/
/** @var DOMNode[] * */
private array $correctAnswer = [];

private bool $foundPossibleAnswers = false;
private bool $foundCorrectAnswer = false;

public function __construct(private readonly string $document)
{
}

/**
* @return void
* @return array{question: DOMNode[], possible_answers: DOMNode[], correct_answer:DOMNode[] }
*/
public function extract(): void
public function extract(string $document): array
{
$domDocument = new DOMDocument();
libxml_use_internal_errors(true);
$domDocument->loadHTML($this->document);
$domDocument->loadHTML($document);

$this->process($domDocument);

return [
'question' => $this->question,
'possible_answers' => $this->possibleAnswers,
'correct_answer' => $this->correctAnswer
];
}

public function process(DOMNode $domNode): void
Expand Down Expand Up @@ -72,19 +74,19 @@ public function process(DOMNode $domNode): void
}
}

/** @return DOMNode[] **/
/** @return DOMNode[] * */
public function getQuestionNodes(): array
{
return $this->question;
}

/** @return DOMNode[] **/
/** @return DOMNode[] * */
public function getPossibleAnswerNodes(): array
{
return $this->possibleAnswers;
}

/** @return DOMNode[] **/
/** @return DOMNode[] * */
public function getCorrectAnswerNodes(): array
{
return $this->correctAnswer;
Expand Down
30 changes: 30 additions & 0 deletions api/src/Markdown/Parser/MarkdownParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace App\Markdown\Parser;

use App\Markdown\Extractor\DOMExtractor;
use App\Markdown\Model\Question;
use Parsedown;

class MarkdownParser
{
public function __construct(private readonly Parsedown $parsedown, private readonly DOMExtractor $DOMExtractor)
{
}


public function parser(Question $question): Question
{
$filePath = $question->getFilePath();
$markdown = file_get_contents($filePath);

$html = $this->parsedown->parse($markdown);

$parts = $this->DOMExtractor->extract($html);

$question->setContent($parts['question'])
->setCorrectAnswer($parts['correct_answer'])
->setPossibleAnswers($parts['possible_answers']);
return $question;
}
}
4 changes: 3 additions & 1 deletion api/src/Markdown/QuestionGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
namespace App\Markdown;

use App\Markdown\Model\Question;
use App\Markdown\Parser\MarkdownParser;

class QuestionGenerator implements GeneratorInterface
{
public function __construct(private readonly FetcherInterface $fetcher)
public function __construct(private readonly FetcherInterface $fetcher, private readonly MarkdownParser $markdownParser)
{
}

Expand Down Expand Up @@ -74,6 +75,7 @@ public function process(array $filePaths): array
}

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

$dataSets[] = $question;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ public function setUp(): void

public function testAnswerElement()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$questionNodes = $parser->getCorrectAnswerNodes();

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

public function testAnswerValue()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$questionNodes = $parser->getCorrectAnswerNodes();

self::assertSame('Answer: 5', trim($questionNodes[4]->nodeValue));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,35 @@ public function setUp(): void

public function testHeadingValue()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$nodes = $parser->getPossibleAnswerNodes();

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

public function testHeadingElement()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$nodes = $parser->getPossibleAnswerNodes();

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

public function testFirstPossibleAnswerValue()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$nodes = $parser->getPossibleAnswerNodes();

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

public function testFirstPossibleAnswerElement()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$nodes = $parser->getPossibleAnswerNodes();

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

public function testLastPossibleAnswerValue()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$nodes = $parser->getPossibleAnswerNodes();
$lastIndex = count($nodes) - 1;

Expand All @@ -65,8 +65,8 @@ public function testLastPossibleAnswerValue()

public function testLastPossibleAnswerElement()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$nodes = $parser->getPossibleAnswerNodes();
$lastIndex = count($nodes) - 1;

Expand Down
16 changes: 8 additions & 8 deletions api/tests/unit/src/Markdown/Extractor/QuestionExtractorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,26 @@ public function setUp(): void

public function testQuestionHeadingValue()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$questionNodes = $parser->getQuestionNodes();

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

public function testQuestionHeadingElement()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$questionNodes = $parser->getQuestionNodes();

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

public function testLastQuestionElement()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$questionNodes = $parser->getQuestionNodes();
$count = count($questionNodes) - 1;

Expand All @@ -47,8 +47,8 @@ public function testLastQuestionElement()

public function testLastQuestionValue()
{
$parser = new DOMExtractor($this->document);
$parser->extract();
$parser = new DOMExtractor();
$parser->extract($this->document);
$questionNodes = $parser->getQuestionNodes();
$count = count($questionNodes) - 1;

Expand Down
27 changes: 23 additions & 4 deletions api/tests/unit/src/Markdown/QuestionGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace App\Tests\unit\src\Markdown;

use App\Markdown\FetcherInterface;
use App\Markdown\Model\Question;
use App\Markdown\Parser\MarkdownParser;
use App\Markdown\QuestionFetcher;
use App\Markdown\QuizFetcher;
use App\Markdown\QuestionGenerator;
Expand Down Expand Up @@ -31,7 +33,13 @@ public function setUp(): void

public function testGeneratedQuestionID()
{
$quizGenerator = new QuestionGenerator($this->fetcherMock);
$question = $this->createMock(Question::class);
$question->expects(self::once())->method('getId')->willReturn(2);

$parserMock = $this->createMock(MarkdownParser::class);
$parserMock->expects(self::any())->method('parser')->willReturn($question);

$quizGenerator = new QuestionGenerator($this->fetcherMock, $parserMock);
$dataSets = $quizGenerator->generate(self::SOURCE);

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

public function testGeneratedQuizID()
{
$quizGenerator = new QuestionGenerator($this->fetcherMock);
$question = $this->createMock(Question::class);
$question->expects(self::once())->method('getQuizId')->willReturn(1);

$parserMock = $this->createMock(MarkdownParser::class);
$parserMock->expects(self::any())->method('parser')->willReturn($question);

$quizGenerator = new QuestionGenerator($this->fetcherMock, $parserMock);
$dataSets = $quizGenerator->generate(self::SOURCE);

$question2 = $dataSets[1];

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


public function testGeneratedTitle()
{
$quizGenerator = new QuestionGenerator($this->fetcherMock);
$question = $this->createMock(Question::class);
$question->expects(self::once())->method('getTitle')->willReturn('Style override');

$parserMock = $this->createMock(MarkdownParser::class);
$parserMock->expects(self::any())->method('parser')->willReturn($question);

$quizGenerator = new QuestionGenerator($this->fetcherMock, $parserMock);
$dataSets = $quizGenerator->generate(self::SOURCE);

$question2 = $dataSets[1];
Expand Down
14 changes: 10 additions & 4 deletions api/tests/unit/src/Markdown/QuestionIDGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Tests\unit\src\Markdown;

use App\Markdown\FetcherInterface;
use App\Markdown\Parser\MarkdownParser;
use App\Markdown\QuestionGenerator;
use PHPUnit\Framework\TestCase;

Expand All @@ -11,31 +12,36 @@ class QuestionIDGeneratorTest extends TestCase
public function testGetQuestionID()
{
$fetcherMock = $this->createMock(FetcherInterface::class);
$generator = new QuestionGenerator($fetcherMock);
$parserMock = $this->createMock(MarkdownParser::class);
$generator = new QuestionGenerator($fetcherMock, $parserMock);
$questionID = $generator->getIDFromFilePath('1_2_style_override.md', false);
self::assertSame(2, $questionID);
}

public function testGetQuestionIDWithDoubleDigits()
{
$fetcherMock = $this->createMock(FetcherInterface::class);
$generator = new QuestionGenerator($fetcherMock);
$parserMock = $this->createMock(MarkdownParser::class);
$generator = new QuestionGenerator($fetcherMock, $parserMock);
$questionID = $generator->getIDFromFilePath('1_20_style_override.md', false);
self::assertSame(20, $questionID);
}

public function testGetQuestionIDWithNoIDValue()
{
$fetcherMock = $this->createMock(FetcherInterface::class);
$generator = new QuestionGenerator($fetcherMock);
$parserMock = $this->createMock(MarkdownParser::class);
$generator = new QuestionGenerator($fetcherMock, $parserMock);
$questionID = $generator->getIDFromFilePath('1.md', false);
self::assertFalse($questionID);
}

public function testGetQuestionIDWithIncorrectValueType()
{
$fetcherMock = $this->createMock(FetcherInterface::class);
$generator = new QuestionGenerator($fetcherMock);
$parserMock = $this->createMock(MarkdownParser::class);
$generator = new QuestionGenerator($fetcherMock, $parserMock);
$questionID = $generator->getIDFromFilePath('1_two.md', false);
$questionID = $generator->getIDFromFilePath('1_two.md', false);
self::assertFalse($questionID);
}
Expand Down
Loading

0 comments on commit 212ea63

Please sign in to comment.