public function testChunk_ReturnsChunkedElementsAccordingToChunksize() { $groups = Linq::from([])->chunk(2); $this->assertEquals(0, $groups->count()); $groups = Linq::from(["a"])->chunk(2); $this->assertEquals(1, $groups->count()); $this->assertEquals(1, $groups->ElementAt(0)->count()); $this->assertEquals("a", $groups->ElementAt(0)->ElementAt(0)); $groups = Linq::from(["a", "b", "c", "d", "e"])->chunk(2); $this->assertEquals(3, $groups->count()); $this->assertEquals(2, $groups->ElementAt(0)->count()); $this->assertEquals("a", $groups->ElementAt(0)->ElementAt(0)); $this->assertEquals("b", $groups->ElementAt(0)->ElementAt(1)); $this->assertEquals(2, $groups->ElementAt(1)->count()); $this->assertEquals("c", $groups->ElementAt(1)->ElementAt(0)); $this->assertEquals("d", $groups->ElementAt(1)->ElementAt(1)); $this->assertEquals(1, $groups->ElementAt(2)->count()); $this->assertEquals("e", $groups->ElementAt(2)->ElementAt(0)); $groups = Linq::from(["a", "b", "c", "d", "e"])->chunk(3); $this->assertEquals(2, $groups->count()); $groups = Linq::from(["a", "b", "c", "d", "e"])->chunk(4); $this->assertEquals(2, $groups->count()); $groups = Linq::from(["a", "b", "c", "d", "e"])->chunk(5); $this->assertEquals(1, $groups->count()); $groups = Linq::from(["a", "b", "c", "d", "e"])->chunk(117); $this->assertEquals(1, $groups->count()); }
public function testGroupBy() { $a1 = new stdClass(); $a1->id = 1; $a1->value = "a"; $a2 = new stdClass(); $a2->id = 2; $a2->value = "a"; $b1 = new stdClass(); $b1->id = 3; $b1->value = "b"; $items = [$a1, $a2, $b1]; $grouped = Linq::from($items)->groupBy(function ($x) { return $x->value; }); $this->assertTrue($grouped instanceof Linq); $this->assertEquals(2, $grouped->count()); $aGroup = $grouped->elementAt(0); $this->assertTrue($aGroup instanceof Fusonic\Linq\GroupedLinq); $this->assertEquals("a", $aGroup->key()); $this->assertEquals(2, $aGroup->count()); $this->assertSame($a1, $aGroup->elementAt(0)); $this->assertSame($a2, $aGroup->elementAt(1)); $bGroup = $grouped->elementAt(1); $this->assertEquals("b", $bGroup->key()); $this->assertEquals(1, $bGroup->count()); $this->assertSame($b1, $bGroup->elementAt(0)); }
public function testWhere_EmptySequence_ReturnsEmptySequence() { $items = []; $matching = Linq::from($items)->where(function ($v) { return true; }); $this->assertEquals(0, $matching->count()); $array = $matching->toArray(); $this->assertEquals(0, count($array)); }
public function testWhereOrderBy_returnsFilteredValuesInCorrectOrder() { $source = [1, 4, 5, 2, 3]; $result = Linq::from($source)->where(function ($x) { return $x > 2; })->orderBy(function ($x) { return $x; }); $this->assertEquals([3, 4, 5], $result->toArray()); // Check multiple evaluations are working as well: $this->assertEquals([3, 4, 5], $result->toArray()); }
public function testMethodsWithSequencesAsArguments_WorkWith_Arrays_Iterators_And_IteratorAggregates() { $first = Linq::from(["a", "b"]); $secondArray = ["c", "d"]; $secondLinq = Linq::from(["c", "d"]); $secondIterator = $secondLinq->getIterator(); $res = $first->concat($secondLinq)->toArray(); $res = $first->intersect($secondLinq)->toArray(); $res = $first->except($secondLinq)->toArray(); $res = $first->concat($secondArray)->toArray(); $res = $first->intersect($secondArray)->toArray(); $res = $first->except($secondArray)->toArray(); $res = $first->concat($secondIterator)->toArray(); $res = $first->intersect($secondIterator)->toArray(); $res = $first->except($secondIterator)->toArray(); }
public function getIterator() { $chunk = []; $current = 0; foreach ($this->iterator as $d) { $current++; $chunk[] = $d; if ($current >= $this->chunkSize) { (yield Linq::from($chunk)); $chunk = []; $current = 0; } } if (count($chunk) > 0) { (yield Linq::from($chunk)); } }
public function testContains_defaultComparison() { $items = ["2", 2]; $linq = Linq::from($items); $this->assertTrue($linq->contains(2)); $this->assertTrue($linq->contains("2")); $this->assertFalse($linq->contains(true)); $this->assertFalse($linq->contains(3)); $this->assertFalse($linq->contains("3")); $this->assertFalse($linq->contains(3)); $this->assertFalse($linq->contains(null)); $a = new stdClass(); $b = new stdClass(); $c = new stdClass(); $linq = Linq::from([$a, $b]); $this->assertTrue($linq->contains($a)); $this->assertTrue($linq->contains($b)); $this->assertFalse($linq->contains($c)); }
public function testRange_returnsRangeOfIntegers() { $range = Linq::range(0, 3)->toArray(); $this->assertEquals(3, count($range)); $this->assertEquals(0, $range[0]); $this->assertEquals(1, $range[1]); $this->assertEquals(2, $range[2]); $range = Linq::range(6, 3)->toArray(); $this->assertEquals(3, count($range)); $this->assertEquals(6, $range[0]); $this->assertEquals(7, $range[1]); $this->assertEquals(8, $range[2]); $range = Linq::range(-3, 5)->toArray(); $this->assertEquals(5, count($range)); $this->assertEquals(-3, $range[0]); $this->assertEquals(-2, $range[1]); $this->assertEquals(-1, $range[2]); $this->assertEquals(0, $range[3]); $this->assertEquals(1, $range[4]); }
private function extractOpenGraphData($content) { $crawler = new Crawler($content); // Get all meta-tags starting with "og:" $ogMetaTags = $crawler->filter("meta[property^='og:']"); // Create clean property array $properties = Linq::from($ogMetaTags)->select(function (\DOMElement $tag) { $name = strtolower(trim($tag->getAttribute("property"))); $value = trim($tag->getAttribute("content")); return new Property($name, $value); })->toArray(); // Create new object of the correct type $typeProperty = Linq::from($properties)->firstOrNull(function (Property $property) { return $property->key === Property::TYPE; }); switch ($typeProperty !== null ? $typeProperty->value : null) { default: $object = new Website(); break; } // Assign all properties to the object $object->assignProperties($properties, $this->debug); // Fallback for title if ($this->useFallbackMode && !$object->title) { $titleElement = $crawler->filter("title")->first(); if ($titleElement) { $object->title = trim($titleElement->text()); } } // Fallback for description if ($this->useFallbackMode && !$object->description) { $descriptionElement = $crawler->filter("meta[property='description']")->first(); if ($descriptionElement) { $object->description = trim($descriptionElement->attr("content")); } } return $object; }
public function __construct($groupKey, $dataSource) { parent::__construct($dataSource); $this->groupKey = $groupKey; }
public function testSelectMany_DoesLazyEvaluation() { $a1 = new stdClass(); $a1->value = ["a", "b"]; $a2 = new stdClass(); $a2->value = ["c", "d"]; $items = [$a1, $a2]; $eval = false; $flattened = Linq::from($items)->selectMany(function ($x) use(&$eval) { $eval = true; return $x->value; }); $this->assertFalse($eval, "SelectMany did execute before iterating!"); $result = $flattened->toArray(); $this->assertTrue($eval); }
public function testIssue3_emtpyCollectionOrdering() { Linq::from([])->orderBy(function (array $x) { return $x["name"]; })->toArray(); }
public function testSkip_WithIteratorAggregate() { $items = new TestIteratorAggregate(["a", "b", "c", "d", "e", "f"]); $matching = Linq::from($items)->skip(2); $this->assertTrue($matching instanceof Linq); $this->assertEquals(4, $matching->count()); }
<?php /* * One important design goal was the principle of the least surprise. * As PHP is a fully dynamic language with nearly no type-safety, it is common to shoot yourself into the foot because of accidentally mixing up incompatible types. * We protect you from these programing errors by asserting that every callback functions you supply to the library must return a correctly typed value. * In addition, every supported aggregate function will throw an exception if you are accidentally mixing up incompatible types. * * This means that we made this library totally predictable in what it does, and verified that every function has its defined exceptions * which are thrown when certain operations fail, or if certain types are not correct. * */ echo "<pre>"; require_once __DIR__ . '/../vendor/autoload.php'; // Autoload files using Composer autoload use Fusonic\Linq\Linq; /* Throws an UnexpectedValueException if the provided callback function does not return a boolean */ Linq::from(["1", "1"])->where(function ($x) { return "NOT A BOOLEAN"; }); /* Throws an UnexpectedValueException if one of the values is not convertible to a numeric value:*/ Linq::from([1, 2, "Not a numeric value"])->sum();
// Calculate the average filesize of all files greater than 1024 bytes in a directory // but skip the very first 2 files and then take only 4 files. ### Plain PHP: ### $sum = 0; $i = 0; $y = 0; foreach ($files as $file) { $currentSize = filesize($file); if ($currentSize > 1024) { if ($y < 2) { $y++; continue; } else { if ($y > 5) { break; } } $y++; $sum += $currentSize; $i++; } } $avg = $sum / $i; echo "Average: " . $avg; ### Linq: ### $avgL = Linq::from($files)->select(function ($x) { return filesize($x); })->where(function ($x) { return $x > 1024; })->skip(2)->take(4)->average(); echo "<br/><br>Average Linq: " . $avgL;
/** * @test */ public function when_ofType_is_called_with_double_as_type() { /** @var int[] $expectedResult */ $expectedResult = array(2.5, 10.0, 0.3); $result = Linq::from(array(0, 'string', 2.5, 10.0, NULL, 11, 'false', 0.3))->ofType('double')->toArray(); $this->assertNotNull($result); $this->assertEquals($expectedResult, $result); }
public function testTake_TakeValuesByAmount() { $items = ["a", "b", "c", "d", "e", "f"]; $matching = Linq::from($items)->take(4); $this->assertTrue($matching instanceof Linq); $this->assertEquals(4, $matching->count()); $matching = $matching->toArray(); $this->assertTrue(in_array("a", $matching)); $this->assertTrue(in_array("b", $matching)); $this->assertTrue(in_array("c", $matching)); $this->assertTrue(in_array("d", $matching)); $matching = Linq::from($items)->take(0); $this->assertEquals(0, $matching->count()); }
<?php /* * One important design goal was the principle of the least surprise. * As PHP is a fully dynamic language with nearly no type-safety, it is common to shoot yourself into the foot because of accidentally mixing up incompatible types. * We protect you from these programing errors by asserting that every callback functions you supply to the library must return a correctly typed value. * In addition, every supported aggregate function will throw an exception if you are accidentally mixing up incompatible types. * * This means that we made this library totally predictable in what it does, and verified that every function has its defined exceptions * which are thrown when certain operations fail, or if certain types are not correct. * */ echo "<pre>"; require_once __DIR__ . '/../vendor/autoload.php'; // Autoload files using Composer autoload use Fusonic\Linq\Linq; /* Throws an UnexpectedValueException if the provided callback function does not return a boolean */ Linq::from(array("1", "1"))->where(function ($x) { return "NOT A BOOLEAN"; }); /* Throws an UnexpectedValueException if one of the values is not convertible to a numeric value:*/ Linq::from(array(1, 2, "Not a numeric value"))->sum();
/** * Splits the sequence in chunks according to $chunksize. * * @param int $chunksize Specifies how many elements are grouped together per chunk. * @throws \InvalidArgumentException * @return Linq */ public function chunk($chunksize) { if ($chunksize < 1) { throw new \InvalidArgumentException("'{$chunksize}' is not a valid chunk size."); } return Linq::from(new ChunkIterator($this->iterator, $chunksize)); }
public function testAggregate_withSeedValue_returnsCorrectResult() { $this->assertEquals(9999, Linq::from([])->aggregate(function () { }, 9999)); $this->assertEquals(104, Linq::from([2])->aggregate(function ($a, $b) { return $a + $b; }, 102)); $this->assertEquals(137, Linq::from([2, 2, 20, 11])->aggregate(function ($a, $b) { return $a + $b; }, 102)); $this->assertEquals("begin_abcde", Linq::from(["a", "b", "c", "d", "e"])->aggregate(function ($a, $b) { return $a . $b; }, "begin_")); }
public function testDistinct_DoesLazyEvaluation() { $eval = false; $a1 = new stdClass(); $a1->id = 1; $a1->value = "a"; $a2 = new stdClass(); $a2->id = 2; $a2->value = "a"; $items = [$a1, $a2]; $distinct = Linq::from($items)->distinct(function ($v) use(&$eval) { $eval = true; return $v->value; }); $this->assertFalse($eval, "SelectMany did execute before iterating!"); $distinct->toArray(); $this->assertTrue($eval); }