77use Brainbits \FunctionalTestHelpers \Schema \DataBuilder ;
88use Brainbits \FunctionalTestHelpers \Schema \SchemaBuilder ;
99use Brainbits \FunctionalTestHelpers \Schema \SchemaTrait ;
10+ use Brainbits \FunctionalTestHelpers \Schema \Strategy \SchemaStrategy ;
1011use Doctrine \DBAL \Connection ;
11- use Doctrine \DBAL \Platforms \SqlitePlatform ;
1212use Doctrine \DBAL \Schema \Schema ;
13+ use PHPUnit \Framework \MockObject \MockObject ;
1314use PHPUnit \Framework \TestCase ;
1415
1516use function getenv ;
@@ -23,75 +24,187 @@ final class SchemaTraitTest extends TestCase
2324
2425 private string $ oldEnvUsePreInitializedSchema ;
2526
27+ private MockObject &Connection $ connectionMock ;
28+ private MockObject &SchemaStrategy $ schemaStrategyMock ;
29+
30+ private SchemaBuilder $ schemaBuilder ;
31+ private DataBuilder $ dataBuilder ;
32+
2633 protected function setUp (): void
2734 {
2835 $ this ->oldEnvUsePreInitializedSchema = (string ) getenv ('USE_PRE_INITIALIZED_SCHEMA ' );
36+
37+ self ::$ isSchemaDatabaseClean = false ;
38+
39+ $ this ->connectionMock = $ this ->createMock (Connection::class);
40+ $ this ->schemaStrategyMock = $ this ->createMock (SchemaStrategy::class);
41+
42+ $ this ->schemaBuilder = $ this ->createSchemaBuilder ();
43+ $ this ->dataBuilder = $ this ->createDataBuilder ();
2944 }
3045
3146 protected function tearDown (): void
3247 {
3348 putenv (sprintf ('USE_PRE_INITIALIZED_SCHEMA=%s ' , $ this ->oldEnvUsePreInitializedSchema ));
3449 }
3550
36- public function testFixtureFromConnectionWithTableNameQuote (): void
51+ public function testFixtureFromNewConnectionExecutesBuildDataCallback (): void
52+ {
53+ $ callbackHasBeenCalled = false ;
54+
55+ $ this ->fixtureFromNewConnection (
56+ $ this ->schemaBuilder ,
57+ $ this ->dataBuilder ,
58+ function ($ dataBuilderInCallback ) use (&$ callbackHasBeenCalled ): void {
59+ self ::assertSame ($ this ->dataBuilder , $ dataBuilderInCallback );
60+
61+ $ callbackHasBeenCalled = true ;
62+ },
63+ );
64+
65+ self ::assertTrue ($ callbackHasBeenCalled );
66+ }
67+
68+ public function testFixtureFromNewConnectionAppliesSchemaAndData (): void
69+ {
70+ $ this ->schemaStrategyMock ->expects ($ this ->once ())
71+ ->method ('applySchema ' )
72+ ->with ($ this ->schemaBuilder , $ this ->isInstanceOf (Connection::class));
73+
74+ $ this ->schemaStrategyMock ->expects ($ this ->once ())
75+ ->method ('applyData ' )
76+ ->with ($ this ->dataBuilder , $ this ->isInstanceOf (Connection::class));
77+
78+ $ this ->fixtureFromNewConnection (
79+ $ this ->schemaBuilder ,
80+ $ this ->dataBuilder ,
81+ static fn () => null ,
82+ );
83+ }
84+
85+ public function testFixtureFromConnectionExecutesBuildDataCallback (): void
3786 {
38- $ schemaBuilder = $ this ->createSchemaBuilder ();
39- $ dataBuilder = $ this ->createDataBuilder ($ schemaBuilder );
40-
41- $ connection = $ this ->createMock (Connection::class);
42- $ connection ->expects ($ this ->any ())
43- ->method ('getParams ' )
44- ->willReturn (['driver ' => 'pdo_sqlite ' , 'memory ' => true ]);
45- $ connection ->expects ($ this ->any ())
46- ->method ('getDatabasePlatform ' )
47- ->willReturn (new SqlitePlatform ());
48- $ connection ->expects ($ this ->once ())
49- ->method ('executeStatement ' )
50- ->with ('CREATE TABLE foo (bar VARCHAR(255) NOT NULL) ' );
51- $ connection ->expects ($ this ->once ())
52- ->method ('insert ' )
53- ->with ('"foo" ' , ['"bar" ' => 'baz ' ]);
87+ $ callbackHasBeenCalled = false ;
5488
5589 $ this ->fixtureFromConnection (
56- $ connection ,
57- $ schemaBuilder ,
58- $ dataBuilder ,
59- static function ($ dataBuilder ): void {
60- $ dataBuilder ->foo ('baz ' );
90+ $ this ->connectionMock ,
91+ $ this ->schemaBuilder ,
92+ $ this ->dataBuilder ,
93+ function ($ dataBuilderInCallback ) use (&$ callbackHasBeenCalled ): void {
94+ self ::assertSame ($ this ->dataBuilder , $ dataBuilderInCallback );
95+
96+ $ callbackHasBeenCalled = true ;
6197 },
6298 );
99+
100+ self ::assertTrue ($ callbackHasBeenCalled );
101+ }
102+
103+ public function testFixtureFromConnectionAppliesSchemaAndData (): void
104+ {
105+ $ this ->schemaStrategyMock ->expects ($ this ->once ())
106+ ->method ('applySchema ' )
107+ ->with ($ this ->schemaBuilder , $ this ->connectionMock );
108+
109+ $ this ->schemaStrategyMock ->expects ($ this ->once ())
110+ ->method ('applyData ' )
111+ ->with ($ this ->dataBuilder , $ this ->connectionMock );
112+
113+ $ this ->fixtureFromConnection (
114+ $ this ->connectionMock ,
115+ $ this ->schemaBuilder ,
116+ $ this ->dataBuilder ,
117+ static fn () => null ,
118+ );
63119 }
64120
65121 public function testFixtureFromConnectionWithPreInitializedSchema (): void
66122 {
67123 putenv ('USE_PRE_INITIALIZED_SCHEMA=1 ' );
68124
69- $ schemaBuilder = $ this ->createSchemaBuilder ();
70- $ dataBuilder = $ this ->createDataBuilder ($ schemaBuilder );
71-
72- $ connection = $ this ->createMock (Connection::class);
73- $ connection ->expects ($ this ->any ())
74- ->method ('getParams ' )
75- ->willReturn (['driver ' => 'pdo_sqlite ' , 'memory ' => true ]);
76- $ connection ->expects ($ this ->any ())
77- ->method ('getDatabasePlatform ' )
78- ->willReturn (new SqlitePlatform ());
79- $ connection ->expects ($ this ->never ())
80- ->method ('executeStatement ' );
81- $ connection ->expects ($ this ->once ())
82- ->method ('insert ' )
83- ->with ('"foo" ' , ['"bar" ' => 'baz ' ]);
125+ $ this ->schemaStrategyMock ->expects ($ this ->never ())
126+ ->method ('applySchema ' );
127+
128+ $ this ->schemaStrategyMock ->expects ($ this ->once ())
129+ ->method ('applyData ' )
130+ ->with ($ this ->dataBuilder , $ this ->connectionMock );
84131
85132 $ this ->fixtureFromConnection (
86- $ connection ,
87- $ schemaBuilder ,
88- $ dataBuilder ,
89- static function ($ dataBuilder ): void {
90- $ dataBuilder ->foo ('baz ' );
91- },
133+ $ this ->connectionMock ,
134+ $ this ->schemaBuilder ,
135+ $ this ->dataBuilder ,
136+ static fn () => null ,
137+ );
138+ }
139+
140+ public function testSchemaIsCleanedUpBeforeApplyingDataIfDatabaseIsDirty (): void
141+ {
142+ self ::$ isSchemaDatabaseClean = false ;
143+
144+ $ this ->schemaStrategyMock ->expects ($ this ->once ())
145+ ->method ('deleteData ' )
146+ ->with ($ this ->connectionMock );
147+
148+ $ this ->schemaStrategyMock ->expects ($ this ->once ())
149+ ->method ('resetSequences ' )
150+ ->with ($ this ->connectionMock );
151+
152+ $ this ->fixtureFromConnection (
153+ $ this ->connectionMock ,
154+ $ this ->schemaBuilder ,
155+ $ this ->dataBuilder ,
156+ static fn () => null ,
157+ );
158+ }
159+
160+ public function testSchemaIsNotCleanedUpBeforeApplyingDataIfDatabaseIsClean (): void
161+ {
162+ self ::$ isSchemaDatabaseClean = true ;
163+
164+ $ this ->schemaStrategyMock ->expects ($ this ->never ())
165+ ->method ('deleteData ' );
166+
167+ $ this ->schemaStrategyMock ->expects ($ this ->never ())
168+ ->method ('resetSequences ' );
169+
170+ $ this ->fixtureFromConnection (
171+ $ this ->connectionMock ,
172+ $ this ->schemaBuilder ,
173+ $ this ->dataBuilder ,
174+ static fn () => null ,
92175 );
93176 }
94177
178+ public function testDatabaseIsMarkedDirtyIfDataWasApplied (): void
179+ {
180+ self ::$ isSchemaDatabaseClean = true ;
181+
182+ $ this ->fixtureFromConnection (
183+ $ this ->connectionMock ,
184+ $ this ->schemaBuilder ,
185+ $ this ->dataBuilder ,
186+ static fn () => null ,
187+ );
188+
189+ self ::assertFalse (self ::$ isSchemaDatabaseClean );
190+ }
191+
192+ public function testDatabaseIsMarkedCleanAfterFixupIsCleanedUp (): void
193+ {
194+ self ::$ isSchemaDatabaseClean = false ;
195+
196+ $ this ->fixtureFromConnection (
197+ $ this ->connectionMock ,
198+ $ this ->schemaBuilder ,
199+ $ this ->dataBuilder ,
200+ static fn () => null ,
201+ );
202+
203+ $ this ->cleanupFixture ();
204+
205+ self ::assertTrue (self ::$ isSchemaDatabaseClean );
206+ }
207+
95208 private function createSchemaBuilder (): SchemaBuilder
96209 {
97210 return new class implements SchemaBuilder {
@@ -111,46 +224,37 @@ public function getSchema(): Schema
111224 {
112225 return $ this ->schema ;
113226 }
114-
115- public function foo (): void
116- {
117- $ table = $ this ->schema ->createTable ('foo ' );
118- $ table ->addColumn ('bar ' , 'string ' );
119- }
120227 };
121228 }
122229
123- private function createDataBuilder (SchemaBuilder | null $ schemaBuilder = null ): DataBuilder
230+ private function createDataBuilder (): DataBuilder
124231 {
125- if (!$ schemaBuilder ) {
126- $ schemaBuilder = $ this ->createSchemaBuilder ();
127- }
128-
129- return new class ($ schemaBuilder ) implements DataBuilder {
232+ return new class () implements DataBuilder {
130233 /** @var mixed[] */
131234 private array $ data = [];
132235
133- public function __construct (private SchemaBuilder $ schemaBuilder )
236+ public function __construct ()
134237 {
135238 }
136239
137- public static function create (SchemaBuilder $ schemaBuilder ): DataBuilder
240+ public static function create (): DataBuilder
138241 {
139- return new self ($ schemaBuilder );
242+ return new self ();
140243 }
141244
142245 /** @return mixed[] */
143246 public function getData (): array
144247 {
145248 return $ this ->data ;
146249 }
147-
148- public function foo (string $ bar ): void
149- {
150- $ this ->schemaBuilder ->foo ();
151-
152- $ this ->data ['foo ' ][] = ['bar ' => $ bar ];
153- }
154250 };
155251 }
252+
253+ /**
254+ * Overridden this method to use a schema strategy mock.
255+ */
256+ protected function createSchemaStrategy (Connection $ connection ): SchemaStrategy
257+ {
258+ return $ this ->schemaStrategyMock ;
259+ }
156260}
0 commit comments