22declare (strict_types=1 );
33
44use Behat \Behat \Context \Context ;
5- use Leviy \ReleaseTool \Changelog \ChangelogGenerator ;
5+ use Behat \Gherkin \Node \PyStringNode ;
6+ use Leviy \ReleaseTool \Changelog \Formatter \MarkdownFormatter ;
7+ use Leviy \ReleaseTool \Changelog \PullRequestChangelogGenerator ;
8+ use Leviy \ReleaseTool \GitHub \GitHubClient ;
69use Leviy \ReleaseTool \Interaction \InformationCollector ;
10+ use Leviy \ReleaseTool \ReleaseAction \GitHubReleaseAction ;
711use Leviy \ReleaseTool \ReleaseManager ;
12+ use Leviy \ReleaseTool \Vcs \Commit ;
13+ use Leviy \ReleaseTool \Vcs \Git ;
814use Leviy \ReleaseTool \Vcs \VersionControlSystem ;
915use Leviy \ReleaseTool \Versioning \SemanticVersioning ;
1016use Mockery \MockInterface ;
11- use PHPUnit \Framework \Assert ;
1217
1318class FeatureContext implements Context
1419{
@@ -23,29 +28,42 @@ class FeatureContext implements Context
2328 private $ releaseManager ;
2429
2530 /**
26- * @var string|null
31+ * @var MockInterface|InformationCollector
2732 */
28- private $ nextVersion ;
33+ private $ informationCollector ;
2934
3035 /**
31- * @var MockInterface|InformationCollector
36+ * @var MockInterface|GitHubClient
3237 */
33- private $ informationCollector ;
38+ private $ githubClient ;
39+
40+ /**
41+ * @var Commit[]
42+ */
43+ private $ mergedPullRequests = [];
3444
3545 public function __construct ()
3646 {
3747 $ this ->informationCollector = Mockery::mock (InformationCollector::class);
38- $ this ->versionControlSystem = Mockery::mock (VersionControlSystem::class);
48+
49+ $ this ->versionControlSystem = Mockery::mock (Git::class);
3950 $ this ->versionControlSystem ->shouldIgnoreMissing ();
4051
41- $ changelogGenerator = Mockery::mock (ChangelogGenerator::class);
42- $ changelogGenerator ->shouldReceive ('getChanges ' )->andReturn ([]);
52+ $ changelogGenerator = new PullRequestChangelogGenerator ($ this ->versionControlSystem );
53+
54+ $ this ->githubClient = Mockery::spy (GitHubClient::class);
55+
56+ $ githubReleaseAction = new GitHubReleaseAction (
57+ $ changelogGenerator ,
58+ new MarkdownFormatter ([]),
59+ $ this ->versionControlSystem ,
60+ $ this ->githubClient
61+ );
4362
4463 $ this ->releaseManager = new ReleaseManager (
4564 $ this ->versionControlSystem ,
4665 new SemanticVersioning (),
47- $ changelogGenerator ,
48- []
66+ [$ githubReleaseAction ]
4967 );
5068 }
5169
@@ -65,7 +83,22 @@ public function iReleaseANewVersion(?string $type = null): void
6583 {
6684 $ this ->selectVersionType ($ type );
6785
68- $ this ->nextVersion = $ this ->releaseManager ->determineNextVersion ($ this ->informationCollector );
86+ $ version = $ this ->releaseManager ->determineNextVersion ($ this ->informationCollector );
87+ $ this ->releaseManager ->release ($ version , $ this ->informationCollector );
88+ }
89+
90+ /**
91+ * @When I release version :version
92+ */
93+ public function iReleaseVersion (string $ version ): void
94+ {
95+ $ this ->versionControlSystem ->shouldReceive ('getCommitsForVersion ' )
96+ ->with ($ version , Mockery::any ())
97+ ->andReturn ($ this ->mergedPullRequests );
98+
99+ $ this ->versionControlSystem ->shouldReceive ('getTagForVersion ' )->andReturn ($ version );
100+ $ this ->informationCollector ->shouldReceive ('askConfirmation ' )->andReturnTrue ();
101+ $ this ->releaseManager ->release ($ version , $ this ->informationCollector );
69102 }
70103
71104 /**
@@ -92,16 +125,50 @@ public function iReleaseAPreReleaseVersion(string $preReleaseType, ?string $type
92125 return ;
93126 }
94127
128+ $ this ->informationCollector ->shouldReceive ('askConfirmation ' )->andReturnTrue ();
95129 $ this ->informationCollector ->shouldReceive ('askMultipleChoice ' )->andReturn ($ answer );
96- $ this ->nextVersion = $ this ->releaseManager ->determineNextPreReleaseVersion ($ this ->informationCollector );
130+
131+ $ version = $ this ->releaseManager ->determineNextPreReleaseVersion ($ this ->informationCollector );
132+ $ this ->releaseManager ->release ($ version , $ this ->informationCollector );
97133 }
98134
99135 /**
100136 * @Then version :version should be released
101137 */
102138 public function versionShouldBeReleased (string $ version ): void
103139 {
104- Assert::assertSame ($ version , $ this ->nextVersion );
140+ $ this ->versionControlSystem ->shouldHaveReceived ('createVersion ' , [$ version ]);
141+ }
142+
143+ /**
144+ * @Given the pre-release :version was created
145+ */
146+ public function wasAPreRelease (string $ version ): void
147+ {
148+ $ this ->versionControlSystem ->shouldReceive ('getPreReleasesForVersion ' )->andReturn ([$ version ]);
149+ $ this ->versionControlSystem ->shouldReceive ('getCommitsForVersion ' )
150+ ->with ($ version , Mockery::any ())
151+ ->andReturn ($ this ->mergedPullRequests );
152+
153+ $ this ->mergedPullRequests = [];
154+ }
155+
156+ /**
157+ * @Then a release with title :title should be published on GitHub with the following release notes:
158+ */
159+ public function aReleaseWithTitleShouldBePublishedOnGitHubWithTheFollowingReleaseNotes (
160+ string $ version ,
161+ PyStringNode $ releaseNotes
162+ ) {
163+ $ this ->githubClient ->shouldHaveReceived ('createRelease ' , [Mockery::any (), $ version , $ releaseNotes ->getRaw ()]);
164+ }
165+
166+ /**
167+ * @Given pull request :title with number :number was merged
168+ */
169+ public function pullRequestWasMerged (string $ title , string $ number )
170+ {
171+ $ this ->mergedPullRequests [] = new Commit ('Merge pull request # ' . $ number . ' from branch ' , $ title );
105172 }
106173
107174 private function selectVersionType (?string $ type ): void
@@ -121,6 +188,10 @@ private function selectVersionType(?string $type): void
121188 break ;
122189 }
123190
191+ // Always respond positive to the question "Do you want to push it to the remote repository and perform
192+ // additional release steps?"
193+ $ answers [] = true ;
194+
124195 $ this ->informationCollector ->shouldReceive ('askConfirmation ' )->andReturn (...$ answers );
125196 }
126197}
0 commit comments