Skip to content

Commit

Permalink
Merge branch 'super-dm3-main'
Browse files Browse the repository at this point in the history
  • Loading branch information
jakejackson1 committed Nov 7, 2024
2 parents 020143c + bb27bf0 commit a664e77
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 91 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ docs/*
doc/*
test/fakepear
vendor/
composer.lock
composer.lock
.phpunit.result.cache
.idea/
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ QueryPath Changelog
# 4.0.1

- Only define global functions qp(), htmlqp(), and html5qp() if they haven't been defined already.
- Fix for :nth-child(n+B) to select B-th and all following elements
- Fix for :nth-child(-n+B) to select first B elements
- Update PHPUnit Test Suite to use @dataProvider in testPseudoClassNthChild() to reduce code repetition

# 4.0.0

Expand Down
10 changes: 8 additions & 2 deletions src/CSS/QueryPathEventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -734,9 +734,15 @@ protected function parseAnB($rule)
throw new ParseException("nth-child value is invalid.");
}

// Each of these is legal: 1, -1, and -. '-' is shorthand for -1.
// Each of these is legal: 1, -1, - and <empty>. '-' is shorthand for -1. <empty> is shorthand for 1
$aVal = trim($rule[0]);
$aVal = ($aVal == '-') ? -1 : (int) $aVal;
if ($aVal === '') {
$aVal = 1;
} elseif ($aVal === '-') {
$aVal = -1;
} else {
$aVal = (int) $aVal;
}

$bVal = ! empty($rule[1]) ? (int) trim($rule[1]) : 0;

Expand Down
124 changes: 36 additions & 88 deletions tests/QueryPath/CSS/QueryPathEventHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,34 @@ public function testChildAtIndex() {
$this->assertEquals('one', $this->nthMatch($matches, 1)->getAttribute('id'));
}*/

public function testPseudoClassNthChild()
public function nthChildProvider(): array
{
return [
[':root :even', 3, 'four' ], // full list
['i:even', 2, 'four' ], // restricted to specific element
['i:odd', 3, 'three' ], // restricted to specific element, odd this time
['i:nth-child(odd)', 3, 'three' ], // odd
['i:nth-child(2n+1)', 3, 'three' ], // odd, equiv to 2n + 1
['i:nth-child(2n-1)', 3, 'three' ], // odd, equiv to 2n + 1
['i:nth-child(2n)', 2, 'four' ], // even
['i:nth-child(-2n)', 0, null ], // empty list (An+B will only accept positive results and without B this will always be negative)
['i:nth-child(-2n+4)', 2, 'two', 0 ], // two and four only
['i:nth-child(-2n+4)', 2, 'four', 1 ], // two and four only
['i:nth-child(4n)', 1, 'four', 0 ], // every fourth row
['i:nth-child(4n+1)', 2, 'five' ], // first of every four rows
['i:nth-child(1)', 1, 'one', 0 ], // first row
['i:nth-child(0n-0)', 0, null ], // empty list
['i:nth-child(n+3)', 3, 'four' ], // third+ lines
['i:nth-child(-n+3)', 3, 'two' ], // first three elements
['i:nth-child(-n+4)', 4, 'two' ], // first four lines
['i:nth-child(0n+2)', 1, 'two', 0 ], // second element in a group of siblings
];
}

/**
* @dataProvider nthChildProvider
*/
public function testPseudoClassNthChild($selector, $matchesCount, $matchId, $matchIndex = 1)
{
$xml = '<?xml version="1.0" ?>
<test>
Expand All @@ -631,95 +658,16 @@ public function testPseudoClassNthChild()

// Test full list
$handler = new QueryPathEventHandler($doc);
$handler->find(':root :even');
$matches = $handler->getMatches();
$this->assertEquals(3, $matches->count());
$this->assertEquals('four', $this->nthMatch($matches, 1)->getAttribute('id'));

// Test restricted to specific element
$handler = new QueryPathEventHandler($doc);
$handler->find('i:even');
$matches = $handler->getMatches();
$this->assertEquals(2, $matches->count());
$this->assertEquals('four', $this->nthMatch($matches, 1)->getAttribute('id'));

// Test restricted to specific element, odd this time
$handler = new QueryPathEventHandler($doc);
$handler->find('i:odd');
$matches = $handler->getMatches();
$this->assertEquals(3, $matches->count());
$this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));

// Test nth-child(odd)
$handler = new QueryPathEventHandler($doc);
$handler->find('i:nth-child(odd)');
$matches = $handler->getMatches();
$this->assertEquals(3, $matches->count());
$this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));

// Test nth-child(2n+1)
$handler = new QueryPathEventHandler($doc);
$handler->find('i:nth-child(2n+1)');
$matches = $handler->getMatches();
$this->assertEquals(3, $matches->count());
$this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));

// Test nth-child(2n) (even)
$handler = new QueryPathEventHandler($doc);
$handler->find('i:nth-child(2n)');
$handler->find($selector);
$matches = $handler->getMatches();
$this->assertEquals(2, $matches->count());
$this->assertEquals('four', $this->nthMatch($matches, 1)->getAttribute('id'));

// Not totally sure what should be returned here
// Test nth-child(-2n)
// $handler = new QueryPathEventHandler($doc);
// $handler->find('i:nth-child(-2n)');
// $matches = $handler->getMatches();
// $this->assertEquals(2, $matches->count());
// $this->assertEquals('four', $this->nthMatch($matches, 1)->getAttribute('id'));

// Test nth-child(2n-1) (odd, equiv to 2n + 1)
$handler = new QueryPathEventHandler($doc);
$handler->find('i:nth-child(2n-1)');
$matches = $handler->getMatches();
$this->assertEquals(3, $matches->count());
$this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));

// Test nth-child(4n) (every fourth row)
$handler = new QueryPathEventHandler($doc);
$handler->find('i:nth-child(4n)');
$matches = $handler->getMatches();
$this->assertEquals(1, $matches->count());
$this->assertEquals('four', $this->nthMatch($matches, 0)->getAttribute('id'));

// Test nth-child(4n+1) (first of every four rows)
$handler = new QueryPathEventHandler($doc);
$handler->find('i:nth-child(4n+1)');
$matches = $handler->getMatches();
// Should match rows one and five
$this->assertEquals(2, $matches->count());
$this->assertEquals('five', $this->nthMatch($matches, 1)->getAttribute('id'));

// Test nth-child(1) (First row)
$handler = new QueryPathEventHandler($doc);
$handler->find('i:nth-child(1)');
$matches = $handler->getMatches();
$this->assertEquals(1, $matches->count());
$this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));

// Test nth-child(0n-0) (Empty list)
$handler = new QueryPathEventHandler($doc);
$handler->find('i:nth-child(0n-0)');
$matches = $handler->getMatches();
$this->assertEquals(0, $matches->count());

// Test nth-child(-n+3) (First three lines)
// $handler = new QueryPathEventHandler($doc);
// $handler->find('i:nth-child(-n+3)');
// $matches = $handler->getMatches();
// $this->assertEquals(3, $matches->count());
$this->assertEquals($matchesCount, $matches->count());
if ($matchesCount) {
$this->assertEquals($matchId, $this->nthMatch($matches, $matchIndex)->getAttribute('id'));
}
}

public function testPseudoClassNthChildNested()
{
$xml = '<?xml version="1.0" ?>
<test>
<i class="odd" id="one"/>
Expand Down

0 comments on commit a664e77

Please sign in to comment.