55use Mockery \MockInterface ;
66use Psr \Cache \CacheItemInterface ;
77use Psr \Cache \CacheItemPoolInterface ;
8- use ScriptFUSION \Porter \Cache \CacheAdvice ;
98use ScriptFUSION \Porter \Cache \CacheKeyGenerator ;
109use ScriptFUSION \Porter \Cache \InvalidCacheKeyException ;
11- use ScriptFUSION \Porter \Cache \JsonCacheKeyGenerator ;
12- use ScriptFUSION \Porter \Cache \MemoryCache ;
1310use ScriptFUSION \Porter \Connector \CachingConnector ;
1411use ScriptFUSION \Porter \Connector \ConnectionContext ;
12+ use ScriptFUSION \Porter \Connector \Connector ;
1513use ScriptFUSION \Porter \Options \EncapsulatedOptions ;
1614use ScriptFUSIONTest \FixtureFactory ;
1715use ScriptFUSIONTest \Stubs \TestOptions ;
@@ -21,10 +19,15 @@ final class CachingConnectorTest extends \PHPUnit_Framework_TestCase
2119 use MockeryPHPUnitIntegration;
2220
2321 /**
24- * @var CachingConnector|MockInterface $connector
22+ * @var CachingConnector $connector
2523 */
2624 private $ connector ;
2725
26+ /**
27+ * @var Connector|MockInterface
28+ */
29+ private $ wrappedConnector ;
30+
2831 /**
2932 * @var ConnectionContext
3033 */
@@ -37,143 +40,147 @@ final class CachingConnectorTest extends \PHPUnit_Framework_TestCase
3740
3841 protected function setUp ()
3942 {
40- $ this ->connector = \Mockery::mock (CachingConnector::class, [])->makePartial ()
41- ->shouldReceive ('fetchFreshData ' )
42- ->andReturn ('foo ' , 'bar ' )
43- ->getMock ();
43+ $ this ->connector = new CachingConnector (
44+ $ this ->wrappedConnector = \Mockery::mock (Connector::class)
45+ ->shouldReceive ('fetch ' )
46+ ->andReturn ('foo ' , 'bar ' )
47+ ->getMock ()
48+ );
4449
45- $ this ->context = FixtureFactory::buildConnectionContext (CacheAdvice:: SHOULD_CACHE () );
50+ $ this ->context = FixtureFactory::buildConnectionContext (true );
4651
4752 $ this ->options = new TestOptions ;
4853 }
4954
55+ /**
56+ * Tests that when cache is enabled, the same result is returned because the wrapped connector is bypassed.
57+ */
5058 public function testCacheEnabled ()
5159 {
5260 self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ this ->options ));
5361 self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ this ->options ));
5462 }
5563
64+ /**
65+ * Tests that when cache is disabled, different results are returned from the wrapped connector.
66+ */
5667 public function testCacheDisabled ()
5768 {
58- $ context = FixtureFactory::buildConnectionContext (CacheAdvice::SHOULD_NOT_CACHE ());
69+ // The default connection context has caching disabled.
70+ $ context = FixtureFactory::buildConnectionContext ();
5971
6072 self ::assertSame ('foo ' , $ this ->connector ->fetch ($ context , 'baz ' , $ this ->options ));
6173 self ::assertSame ('bar ' , $ this ->connector ->fetch ($ context , 'baz ' , $ this ->options ));
6274 }
6375
64- public function testCacheAvailable ()
76+ /**
77+ * Tests that when sources are the same but options are different, the cache is not reused.
78+ */
79+ public function testCacheBypassedForDifferentOptions ()
6580 {
66- self ::assertTrue ($ this ->connector ->isCacheAvailable ());
81+ self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ this ->options ));
82+
83+ $ this ->options ->setFoo ('bar ' );
84+ self ::assertSame ('bar ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ this ->options ));
6785 }
6886
69- public function testGetSetCache ()
87+ /**
88+ * Tests that when the same options are specified by two different object instances, the cache is reused.
89+ */
90+ public function testCacheUsedForDifferentOptionsInstance ()
7091 {
71- self ::assertInstanceOf (CacheItemPoolInterface::class, $ this ->connector ->getCache ());
72- self ::assertNotSame ($ cache = new MemoryCache , $ this ->connector ->getCache ());
73-
74- $ this ->connector ->setCache ($ cache );
75- self ::assertSame ($ cache , $ this ->connector ->getCache ());
92+ self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ this ->options ));
93+ self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , clone $ this ->options ));
7694 }
7795
78- public function testGetSetCacheKeyGenerator ()
96+ public function testNullAndEmptyOptionsAreEquivalent ()
7997 {
80- self :: assertInstanceOf (CacheKeyGenerator::class, $ this -> connector -> getCacheKeyGenerator ());
81- self :: assertNotSame ( $ cacheKeyGenerator = new JsonCacheKeyGenerator , $ this -> connector -> getCacheKeyGenerator () );
98+ /** @var EncapsulatedOptions $options */
99+ $ options = \Mockery:: mock (EncapsulatedOptions::class)-> shouldReceive ( ' copy ' )-> andReturn ([])-> getMock ( );
82100
83- $ this ->connector ->setCacheKeyGenerator ($ cacheKeyGenerator );
84- self ::assertSame ($ cacheKeyGenerator , $ this ->connector ->getCacheKeyGenerator ());
101+ self ::assertEmpty ($ options ->copy ());
102+ self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ options ));
103+ self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' ));
85104 }
86105
87- public function testCacheBypassedForDifferentOptions ()
106+ /**
107+ * Tests that the default cache key generator does not output reserved characters even when comprised of options
108+ * containing them.
109+ */
110+ public function testCacheKeyExcludesReservedCharacters ()
88111 {
89- self :: assertSame ( ' foo ' , $ this -> connector -> fetch ( $ this -> context , ' baz ' , $ this -> options )) ;
112+ $ reservedCharacters = CacheKeyGenerator:: RESERVED_CHARACTERS ;
90113
91- $ this ->options ->setFoo ('bar ' );
92- self ::assertSame ('bar ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ this ->options ));
93- }
114+ $ connector = $ this ->createConnector ($ cache = \Mockery::spy (CacheItemPoolInterface::class));
94115
95- public function testCacheUsedForDifferentOptionsInstance ()
96- {
97- self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ this ->options ));
98- self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , clone $ this ->options ));
116+ $ cache ->shouldReceive ('hasItem ' )
117+ ->andReturnUsing (
118+ function ($ key ) use ($ reservedCharacters ) {
119+ foreach (str_split ($ reservedCharacters ) as $ reservedCharacter ) {
120+ self ::assertNotContains ($ reservedCharacter , $ key );
121+ }
122+ }
123+ )->once ()
124+ ->shouldReceive ('getItem ' )->andReturnSelf ()
125+ ->shouldReceive ('set ' )->andReturn (\Mockery::mock (CacheItemInterface::class))
126+ ;
127+
128+ $ connector ->fetch ($ this ->context , $ reservedCharacters , (new TestOptions )->setFoo ($ reservedCharacters ));
99129 }
100130
101131 /**
102- * Tests that when the cache key generator returns the same hash the same data is fetched, and when it does not,
132+ * Tests that when the cache key generator returns the same key the same data is fetched, and when it does not,
103133 * fresh data is fetched.
104134 */
105135 public function testCacheKeyGenerator ()
106136 {
107- $ this ->connector ->setCacheKeyGenerator (
137+ $ connector = $ this ->createConnector (
138+ null ,
108139 \Mockery::mock (CacheKeyGenerator::class)
109140 ->shouldReceive ('generateCacheKey ' )
110141 ->with ($ source = 'baz ' , $ this ->options ->copy ())
111142 ->andReturn ('qux ' , 'qux ' , 'quux ' )
112143 ->getMock ()
113144 );
114145
115- self ::assertSame ('foo ' , $ this -> connector ->fetch ($ this ->context , $ source , $ this ->options ));
116- self ::assertSame ('foo ' , $ this -> connector ->fetch ($ this ->context , $ source , $ this ->options ));
117- self ::assertSame ('bar ' , $ this -> connector ->fetch ($ this ->context , $ source , $ this ->options ));
146+ self ::assertSame ('foo ' , $ connector ->fetch ($ this ->context , $ source , $ this ->options ));
147+ self ::assertSame ('foo ' , $ connector ->fetch ($ this ->context , $ source , $ this ->options ));
148+ self ::assertSame ('bar ' , $ connector ->fetch ($ this ->context , $ source , $ this ->options ));
118149 }
119150
151+ /**
152+ * TODO: Remove when PHP 5 support dropped.
153+ */
120154 public function testFetchThrowsInvalidCacheKeyExceptionOnNonStringCacheKey ()
121155 {
122- $ this ->connector ->setCacheKeyGenerator (
156+ $ connector = $ this ->createConnector (
157+ null ,
123158 \Mockery::mock (CacheKeyGenerator::class)
124159 ->shouldReceive ('generateCacheKey ' )
125160 ->andReturn (1 )
126161 ->getMock ()
127162 );
128163
129164 $ this ->setExpectedException (InvalidCacheKeyException::class, 'Cache key must be a string. ' );
130- $ this -> connector ->fetch ($ this ->context , 'baz ' , $ this ->options );
165+ $ connector ->fetch ($ this ->context , 'baz ' , $ this ->options );
131166 }
132167
133168 public function testFetchThrowsInvalidCacheKeyExceptionOnNonPSR6CompliantCacheKey ()
134169 {
135- $ this ->connector ->setCacheKeyGenerator (
170+ $ connector = $ this ->createConnector (
171+ null ,
136172 \Mockery::mock (CacheKeyGenerator::class)
137173 ->shouldReceive ('generateCacheKey ' )
138- ->andReturn (CachingConnector ::RESERVED_CHARACTERS )
174+ ->andReturn (CacheKeyGenerator ::RESERVED_CHARACTERS )
139175 ->getMock ()
140176 );
141177
142178 $ this ->setExpectedException (InvalidCacheKeyException::class, 'contains one or more reserved characters ' );
143- $ this ->connector ->fetch ($ this ->context , 'baz ' , $ this ->options );
144- }
145-
146- public function testNullAndEmptyOptionsAreEquivalent ()
147- {
148- /** @var EncapsulatedOptions $options */
149- $ options = \Mockery::mock (EncapsulatedOptions::class)->shouldReceive ('copy ' )->andReturn ([])->getMock ();
150-
151- self ::assertEmpty ($ options ->copy ());
152- self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' , $ options ));
153- self ::assertSame ('foo ' , $ this ->connector ->fetch ($ this ->context , 'baz ' ));
179+ $ connector ->fetch ($ this ->context , 'baz ' , $ this ->options );
154180 }
155181
156- /**
157- * Tests that the default cache key generator does not output reserved characters even when comprised of options
158- * containing them.
159- */
160- public function testCacheKeyExcludesReservedCharacters ()
182+ private function createConnector (MockInterface $ cache = null , MockInterface $ cacheKeyGenerator = null )
161183 {
162- $ reservedCharacters = CachingConnector::RESERVED_CHARACTERS ;
163-
164- $ this ->connector ->setCache ($ cache = \Mockery::spy (CacheItemPoolInterface::class));
165-
166- $ cache ->shouldReceive ('hasItem ' )
167- ->andReturnUsing (
168- function ($ key ) use ($ reservedCharacters ) {
169- foreach (str_split ($ reservedCharacters ) as $ reservedCharacter ) {
170- self ::assertNotContains ($ reservedCharacter , $ key );
171- }
172- }
173- )->once ()
174- ->shouldReceive ('getItem ' )->andReturnSelf ()
175- ->shouldReceive ('set ' )->andReturn (\Mockery::mock (CacheItemInterface::class));
176-
177- $ this ->connector ->fetch ($ this ->context , $ reservedCharacters , (new TestOptions )->setFoo ($ reservedCharacters ));
184+ return new CachingConnector ($ this ->wrappedConnector , $ cache , $ cacheKeyGenerator );
178185 }
179186}
0 commit comments