packages/requirements/tests/Integration/Console/MarkdownCommandTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Integration\Console;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\Attributes\Medium;
10use PHPUnit\Framework\Attributes\UsesClass;
11use PHPUnit\Framework\TestCase;
12use Requirements\Config\MarkdownDocument;
13use Requirements\Console\Application;
14use Requirements\Console\CommandHandler;
15use Requirements\Console\CommandLine;
16use Requirements\Console\Executor;
17use Requirements\Console\Formatter;
18use Requirements\Console\SpecificationReport;
19use Symfony\Component\Process\Process;
20use Tests\Fake\CommandLine as Cli;
21use Tests\Fake\PhpUnitSuite;
22use Tests\Fake\ProjectDirectory;
23
24#[CoversClass(Application::class)]
25#[UsesClass(CommandLine::class)]
26#[UsesClass(CommandHandler::class)]
27#[UsesClass(Executor::class)]
28#[UsesClass(SpecificationReport::class)]
29#[UsesClass(Formatter::class)]
30#[UsesClass(MarkdownDocument::class)]
31#[Medium]
32final class MarkdownCommandTest extends TestCase
33{
34 #[DataProvider('providerCommands')]
35 public function testRunChecksMarkdownAndRunsItsTestWithoutAnExternalMarkdownTool(string $command): void
36 {
37 $project = new ProjectDirectory();
38 $project->write('requirements.yaml', ['version' => 1, 'definitions' => ['definition.md'], 'markdown' => ['experimental' => true], 'runners' => ['unit' => ['extension' => 'phpunit', 'command' => PhpUnitSuite::write($project->directory)]]]);
39 $project->put('definition.md', <<<'MD'
40---
41version: 1
42source: null
43---
44
45# ORIGINAL-001
46
47The converter shall uppercase letters.
48
49**origin**
50
51original
52
53**reason**
54
55Demonstrate the runner contract.
56
57**tests**
58
59- **unit:** Sample\PassingTest::testPass
60MD);
61 $process = new Process([PHP_BINARY, dirname(__DIR__, 3) . '/bin/requirements', $command, '--json'], $project->directory, ['PATH' => '/nonexistent', 'SHELL_VERBOSITY' => false]);
62 $process->run();
63 self::assertSame(0, $process->getExitCode(), $process->getOutput() . $process->getErrorOutput());
64 self::assertStringContainsString('"passed": true', $process->getOutput());
65 }
66
67 /**
68 * @return array<string, array{string}>
69 */
70 public static function providerCommands(): array
71 {
72 return [
73 'lint' => ['lint'],
74 'check' => ['check'],
75 'spec' => ['spec'],
76 'format' => ['format'],
77 ];
78 }
79 public function testManualTestOptionsSurviveFormattingAndControlExecution(): void
80 {
81 $project = new ProjectDirectory();
82 $project->write('requirements.yaml', ['version' => 1, 'definitions' => ['definition.md'], 'markdown' => ['experimental' => true], 'runners' => ['unit' => ['extension' => 'phpunit', 'command' => PhpUnitSuite::write($project->directory)]]]);
83 $project->put('definition.md', <<<'MD'
84---
85version: 1
86source: null
87---
88
89# ORIGINAL-001
90
91The converter shall uppercase letters.
92
93**origin**
94
95original
96
97**reason**
98
99Demonstrate manual tests.
100
101**tests**
102
103- **unit:** Sample\PassingTest::testPass
104 - **run:** auto
105- **unit:** Sample\PassingTest::testFailure
106 - **run:** manual
107- **unit:** Sample\PassingTest::testData
108MD);
109 $format = Cli::run(['format'], $project->directory);
110 self::assertSame(0, $format->getExitCode(), $format->getOutput());
111 self::assertStringContainsString(' - **run:** manual', $project->read('definition.md'));
112 self::assertStringContainsString(' - **run:** auto', $project->read('definition.md'));
113 self::assertSame(0, Cli::run(['format', '--check'], $project->directory)->getExitCode());
114 $default = Cli::run(['spec', '--no-ansi'], $project->directory);
115 self::assertSame(0, $default->getExitCode(), $default->getOutput());
116 self::assertStringContainsString('deferred', $default->getOutput());
117 self::assertStringContainsString('2/3', $default->getOutput());
118 self::assertStringContainsString('use --all', $default->getOutput());
119 $all = Cli::run(['spec', '--all', '--no-ansi'], $project->directory);
120 self::assertSame(1, $all->getExitCode(), $all->getOutput());
121 self::assertStringContainsString('failed', $all->getOutput());
122 }
123}
124