Skip to content

Commit

Permalink
Make add() and remove() operate in an immutable way.
Browse files Browse the repository at this point in the history
Make the cookie collection modifier methods work in an immutable
fashion. This is necessary to preserve the immutability of the
Request/Response objects that we plan on using cookie collections with.

We still need to make the cookies immutable, but that is a separate
task.
  • Loading branch information
markstory committed Mar 17, 2017
1 parent 5dca04a commit 91aeee1
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 17 deletions.
21 changes: 13 additions & 8 deletions src/Http/Cookie/CookieCollection.php
Expand Up @@ -20,6 +20,9 @@

/**
* Cookie Collection
*
* Provides an immutable collection of cookies objects. Adding or removing
* to a collection returns a *new* collection that you must retain.
*/
class CookieCollection implements IteratorAggregate, Countable
{
Expand Down Expand Up @@ -57,17 +60,18 @@ public function count()
}

/**
* Add a cookie to the collection
* Add a cookie and get an updated collection.
*
* @param \Cake\Http\Cookie\CookieInterface $cookie Cookie instance to add.
* @return $this
* @return static
*/
public function add(CookieInterface $cookie)
{
$key = mb_strtolower($cookie->getName());
$this->cookies[$key] = $cookie;
$new = clone $this;
$new->cookies[$key] = $cookie;

return $this;
return $new;
}

/**
Expand Down Expand Up @@ -103,18 +107,19 @@ public function has($name)
}

/**
* Remove a cookie from the collection
* Remove a cookie from the collection and get a new collection
*
* If the cookie is not in the collection, this method will do nothing.
*
* @param string $name The name of the cookie to remove.
* @return $this
* @return static
*/
public function remove($name)
{
unset($this->cookies[mb_strtolower($name)]);
$new = clone $this;
unset($new->cookies[mb_strtolower($name)]);

return $this;
return $new;
}

/**
Expand Down
26 changes: 17 additions & 9 deletions tests/TestCase/Http/Cookie/CookieCollectionTest.php
Expand Up @@ -83,14 +83,19 @@ public function testAdd()
$this->assertCount(0, $collection);

$remember = new Cookie('remember_me', 'a');
$this->assertSame($collection, $collection->add($remember));
$this->assertCount(1, $collection);
$this->assertTrue($collection->has('remember_me'));
$this->assertSame($remember, $collection->get('remember_me'));
$new = $collection->add($remember);
$this->assertNotSame($new, $collection->add($remember));
$this->assertCount(0, $collection, 'Original instance not modified');
$this->assertCount(1, $new);
$this->assertFalse($collection->has('remember_me'), 'Original instance not modified');
$this->assertTrue($new->has('remember_me'));
$this->assertSame($remember, $new->get('remember_me'));

$rememberNo = new Cookie('remember_me', 'no');
$this->assertSame($collection, $collection->add($remember)->add($rememberNo));
$this->assertSame($rememberNo, $collection->get('remember_me'));
$second = $new->add($remember)->add($rememberNo);
$this->assertCount(1, $second);
$this->assertNotSame($second, $new);
$this->assertSame($rememberNo, $second->get('remember_me'));
}

/**
Expand Down Expand Up @@ -125,9 +130,12 @@ public function testRemove()

$collection = new CookieCollection($cookies);
$this->assertInstanceOf(Cookie::class, $collection->get('REMEMBER_me'), 'case insensitive cookie names');
$this->assertSame($collection, $collection->remove('remember_me'));
$this->assertFalse($collection->has('remember_me'));
$this->assertNull($collection->get('remember_me'));
$new = $collection->remove('remember_me');
$this->assertTrue($collection->has('remember_me'), 'old instance not modified');

$this->assertNotSame($new, $collection);
$this->assertFalse($new->has('remember_me'), 'should be removed');
$this->assertNull($new->get('remember_me'), 'should be removed');
}

/**
Expand Down

0 comments on commit 91aeee1

Please sign in to comment.