From f592e272d56d542c4d8b12d781b3cdfdc5d4fe35 Mon Sep 17 00:00:00 2001 From: William Patton Date: Tue, 20 Feb 2018 14:26:19 +0000 Subject: [PATCH 01/11] Fix dropdown opener having empty string for href value. Fixes: #345 --- CHANGELOG.md | 2 ++ class-wp-bootstrap-navwalker.php | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e437055..dc954bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ #CHANGELOG +## [4.0.2] +- Fix dropdown opener having empty string for href value. ## [4.0.1] - Fix untranslated string in fallback (this was lost in transition between v3 and v4, fixed again). diff --git a/class-wp-bootstrap-navwalker.php b/class-wp-bootstrap-navwalker.php index e3ffe94..311f90e 100644 --- a/class-wp-bootstrap-navwalker.php +++ b/class-wp-bootstrap-navwalker.php @@ -11,7 +11,7 @@ * Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker * Description: A custom WordPress nav walker class to implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager. * Author: Edward McIntyre - @twittem, WP Bootstrap, William Patton - @pattonwebz - * Version: 4.0.1 + * Version: 4.0.2-dev * Author URI: https://github.com/wp-bootstrap * GitHub Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker * GitHub Branch: master @@ -189,7 +189,7 @@ public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 $atts['class'] = 'dropdown-toggle nav-link'; $atts['id'] = 'menu-item-dropdown-' . $item->ID; } else { - $atts['href'] = ! empty( $item->url ) ? $item->url : ''; + $atts['href'] = ! empty( $item->url ) ? $item->url : '#'; // Items in dropdowns use .dropdown-item instead of .nav-link. if ( $depth > 0 ) { $atts['class'] = 'dropdown-item'; From bf6dc87c319f2b2b95da4af658774961ed98e856 Mon Sep 17 00:00:00 2001 From: William Patton Date: Thu, 22 Feb 2018 14:18:20 +0000 Subject: [PATCH 02/11] Add unit tests for the function used to seporate classnames --- tests/test-navwalker.php | 295 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 293 insertions(+), 2 deletions(-) diff --git a/tests/test-navwalker.php b/tests/test-navwalker.php index 19b7aed..a5d4344 100644 --- a/tests/test-navwalker.php +++ b/tests/test-navwalker.php @@ -31,14 +31,47 @@ function setUp() { 'container_class' => 'a_container_class', 'menu_class' => 'a_menu_class', 'menu_id' => 'a_menu_id', - 'echo' => true, + 'echo' => true, ); - // array of the possible linkmods. + // array of the possible linkmod typeflags. $this->valid_linkmod_typeflags = array( 'dropdown-header', 'dropdown-divider', ); + + // array of all possible linkmods, including the valid typeflags. + $this->valid_linkmod_classes = array_merge( $this->valid_linkmod_typeflags, array( + 'disabled', + 'sr-only', + ) ); + + // array of valid font-awesome icon class starters plus some randomly chosen icon classes. + $this->some_fontawesome_classes = array( + 'fa', + 'fas', + 'fab', + 'far', + 'fal', + 'fa-android', + 'fa-css3', + 'fa-home', + 'fa-bluetooth-b', + 'fa-chess-rook', + ); + + // array of valid glyphicon icon class starters plus some randomly chosen icon classes. + $this->some_glyphicons_classes = array( + 'glyphicon', + 'glyphicon-asterisk', + 'glyphicon-ok', + 'glyphicon-file', + 'glyphicon-hand-left', + 'glyphicon-sd-video', + 'glyphicon-subscript', + 'glyphicon-grain', + ); + } /** @@ -124,6 +157,9 @@ function test_fallback_function_exists() { * * Expects that for logged out users both echo and return requests should * produce empty strings. + * + * @access public + * @return void */ function test_fallback_function_output_loggedout() { @@ -156,6 +192,9 @@ function test_fallback_function_output_loggedout() { * * Expects strings to be produced with html markup and that they match when * requesting either a return or defaulting to echo. + * + * @access public + * @return void */ function test_fallback_function_output_loggedin() { @@ -206,6 +245,251 @@ function test_seporate_linkmods_and_icons_from_classes_function_exists() { } + /** + * Test that the function catches a random assortment of glyphicon icon + * classes mixed with with regular classnames. + * + * @depends test_seporate_linkmods_and_icons_from_classes_function_exists + * + * @access public + * @return void + */ + function test_seporate_linkmods_and_icons_from_classes_fontawesome() { + + $wp_bootstrap_navwalker = $this->walker; + // since we're working with private methods we need to use a reflector. + $reflector = new ReflectionClass( 'WP_Bootstrap_Navwalker' ); + + // get a reflected method for the opener function and set to public. + $method_open = $reflector->getMethod( 'seporate_linkmods_and_icons_from_classes' ); + $method_open->setAccessible( true ); + + $icons_array = $this->some_fontawesome_classes; + $linkmod_classes = array(); + $icon_classes = array(); + $chars = range( 'a', 'z' ); + $extra_classes = array(); + // make 10 random valid classnames with legth of 8 chars (there should + // be no naming collisions here with this random string gen method). + for ( $i = 0; $i < 20; $i++ ) { + $string = ''; + $length = mt_rand( 4, 10 ); + for ( $j = 0; $j < $length; $j++ ) { + $string .= $chars[ mt_rand( 0, count( $chars ) - 1 ) ]; + } + $extra_classes[] = $string; + } + // merge the valid icon classes with the extra classes and shuffle order. + $icons_array = array_merge( $icons_array, $extra_classes ); + shuffle( $icons_array ); + + $returned_array = $method_open->invokeArgs( $wp_bootstrap_navwalker, array( $icons_array, &$linkmod_classes, &$icon_classes, 0 ) ); + + // linkmod_classes should be empty and returned_array should not. + $this->assertTrue( ( empty( $linkmod_classes ) && ! empty( $returned_array ) ) ); + // icon_classes should no longer be empty. + $this->assertNotTrue( empty( $icon_classes ) ); + // the number of items inside updated $icon_classes should match number of valids we started with. + $this->assertTrue( count( $this->some_fontawesome_classes ) === count( $icon_classes ), "Seems that glyphicons classes are not catptured properly... \nvalid: \n" . print_r( $this->some_fontawesome_classes, true ) . "\nreturned: \n" . print_r( $icon_classes, true ) ); + // get the differences between the original classes and updated classes. + $icon_differences = array_diff( $this->some_fontawesome_classes, $icon_classes ); + // should be no differences thus empty array, this being TRUE also means + // that text was exact match in the updated array vs the original. + $this->assertTrue( empty( $icon_differences ) ); + + } + + /** + * Test that the function catches a random assortment of font awesome icon + * classes mixed with with regular classnames. + * + * @depends test_seporate_linkmods_and_icons_from_classes_function_exists + * + * @access public + * @return void + */ + function test_seporate_linkmods_and_icons_from_classes_glyphicons() { + + $wp_bootstrap_navwalker = $this->walker; + // since we're working with private methods we need to use a reflector. + $reflector = new ReflectionClass( 'WP_Bootstrap_Navwalker' ); + + // get a reflected method for the opener function and set to public. + $method_open = $reflector->getMethod( 'seporate_linkmods_and_icons_from_classes' ); + $method_open->setAccessible( true ); + + $icons_array = $this->some_glyphicons_classes; + $linkmod_classes = array(); + $icon_classes = array(); + $chars = range( 'a', 'z' ); + $extra_classes = array(); + // make 10 random valid classnames with legth of 8 chars (there should + // be no naming collisions here with this random string gen method). + for ( $i = 0; $i < 10; $i++ ) { + $string = ''; + $length = mt_rand( 4, 10 ); + for ( $j = 0; $j < $length; $j++ ) { + $string .= $chars[ mt_rand( 0, count( $chars ) - 1 ) ]; + } + $extra_classes[] = $string; + } + // merge the valid icon classes with the extra classes and shuffle order. + $icons_array = array_merge( $icons_array, $extra_classes ); + shuffle( $icons_array ); + + $returned_array = $method_open->invokeArgs( $wp_bootstrap_navwalker, array( $icons_array, &$linkmod_classes, &$icon_classes, 0 ) ); + + // linkmod_classes should be empty and returned_array should not. + $this->assertTrue( ( empty( $linkmod_classes ) && ! empty( $returned_array ) ) ); + // icon_classes should no longer be empty. + $this->assertNotTrue( empty( $icon_classes ) ); + // the number of items inside updated $icon_classes should match number of valids we started with. + $this->assertTrue( count( $this->some_glyphicons_classes ) === count( $icon_classes ), "Seems that glyphicons classes are not catptured properly... \nvalid: \n" . print_r( $this->some_glyphicons_classes, true ) . "\nreturned: \n" . print_r( $icon_classes, true ) ); + // get the differences between the original classes and updated classes. + $icon_differences = array_diff( $this->some_glyphicons_classes, $icon_classes ); + // should be no differences thus empty array, this being TRUE also means + // that text was exact match in the updated array vs the original. + $this->assertTrue( empty( $icon_differences ) ); + + } + + /** + * Test that the function catches a random assortment of font awesome icon + * classes mixed with with regular classnames. + * + * @depends test_seporate_linkmods_and_icons_from_classes_function_exists + * + * @access public + * @return void + */ + function test_seporate_linkmods_and_icons_from_classes_linkmods() { + + $wp_bootstrap_navwalker = $this->walker; + // since we're working with private methods we need to use a reflector. + $reflector = new ReflectionClass( 'WP_Bootstrap_Navwalker' ); + + // get a reflected method for the opener function and set to public. + $method_open = $reflector->getMethod( 'seporate_linkmods_and_icons_from_classes' ); + $method_open->setAccessible( true ); + + $valid_linkmods = $this->valid_linkmod_classes; + $linkmod_classes = array(); + $icon_classes = array(); + $chars = range( 'a', 'z' ); + $extra_classes = array(); + // make 20 random valid classnames with legth of 4 to 10 chars. There + // should be no naming collisions here with this random string gen. + for ( $i = 0; $i < 10; $i++ ) { + $string = ''; + $length = mt_rand( 4, 10 ); + for ( $j = 0; $j < $length; $j++ ) { + $string .= $chars[ mt_rand( 0, count( $chars ) - 1 ) ]; + } + $extra_classes[] = $string; + } + // merge the valid icon classes with the extra classes and shuffle order. + $linkmod_array = array_merge( $valid_linkmods, $extra_classes ); + shuffle( $linkmod_array ); + + // NOTE: this is depth of 0 and meaning valid_linkmod_typeflags won't be captured. + $returned_array = $method_open->invokeArgs( $wp_bootstrap_navwalker, array( $linkmod_array, &$linkmod_classes, &$icon_classes, 0 ) ); + + // linkmod_classes should NOT be empty and returned_array should not. + $this->assertTrue( ( ! empty( $linkmod_classes ) && ! empty( $returned_array ) ) ); + // icon_classes should be empty. + $this->assertTrue( empty( $icon_classes ) ); + + // the number of items inside updated array should match [what we started with - minus the linkmods for inside dropdowns]. + $this->assertTrue( + (bool) count( ( $this->valid_linkmod_classes ) === ( count( $linkmod_classes ) - count( $this->valid_linkmod_typeflags ) ) ), + "Seems that the linkmod classes are not catptured properly when outside of dropdowns... \nvalid: \n" . print_r( $this->valid_linkmod_classes, true ) . "\nreturned: \n" . print_r( $linkmod_classes, true ) . "\n" . count( $this->valid_linkmod_classes ) . ' ' . count( $linkmod_classes ) . ' ' . count( $this->valid_linkmod_typeflags ) ); + // get the differences between the original classes and updated classes. + $linkmod_differences = array_diff( $this->valid_linkmod_classes, $linkmod_classes, $this->valid_linkmod_typeflags ); + + // should be no differences thus empty array, this being TRUE also means + // that text was exact match in the updated array vs the original. + $this->assertTrue( empty( $linkmod_differences ) ); + + + // repeat some of the above tests but this time with depth = 1 so that we catch classes intended for inside dropdowns. + $depth = 1; + $linkmod_classes_d = array(); + $icon_classes_d = array(); + $returned_array_d = $method_open->invokeArgs( $wp_bootstrap_navwalker, array( $linkmod_array, &$linkmod_classes_d, &$icon_classes_d, $depth ) ); + + $this->assertTrue( count( $this->valid_linkmod_classes ) === count( $linkmod_classes_d ), "Seems that the linkmod classes are not catptured properly when inside dropdowns... \nvalid: \n" . print_r( $this->valid_linkmod_classes, true ) . "\nreturned: \n" . print_r( $linkmod_classes, true ) ); + $linkmod_differences_d = array_diff( $this->valid_linkmod_classes, $linkmod_classes_d ); + $this->assertTrue( empty( $linkmod_differences_d ), 'There are differences between the matched classnames and the valid classnames.' ); + + } + + /** + * Test that the function catches all possible linkmod classes, any icon + * classes and leaves the other classes as-is on the array. + * + * @depends test_seporate_linkmods_and_icons_from_classes_function_exists + * + * @depends test_seporate_linkmods_and_icons_from_classes_fontawesome + * @depends test_seporate_linkmods_and_icons_from_classes_glyphicons + * @depends test_seporate_linkmods_and_icons_from_classes_linkmods + * + * @access public + * @return void + */ + function test_seporate_linkmods_and_icons_from_classes_fulltest() { + + $wp_bootstrap_navwalker = $this->walker; + // since we're working with private methods we need to use a reflector. + $reflector = new ReflectionClass( 'WP_Bootstrap_Navwalker' ); + + // get a reflected method for the opener function and set to public. + $method_open = $reflector->getMethod( 'seporate_linkmods_and_icons_from_classes' ); + $method_open->setAccessible( true ); + + $icons_array = array_merge( $this->some_fontawesome_classes, $this->some_glyphicons_classes ); + $linkmod_array = $this->valid_linkmod_classes; + $linkmod_classes = array(); + $icon_classes = array(); + $chars = range( 'a', 'z' ); + $extra_classes = array(); + // make 1000 random valid classnames with legth of 8 chars (there should + // be no naming collisions here with this random string gen method). + for ( $i = 0; $i < 1000; $i++ ) { + $string = ''; + $length = mt_rand( 4, 10 ); + for ( $j = 0; $j < $length; $j++ ) { + $string .= $chars[ mt_rand( 0, count( $chars ) - 1 ) ]; + } + $extra_classes[] = $string; + } + // merge the valid icon classes with valid linkmod classes and the extra classes then shuffle order. + $classname_array = array_merge( $icons_array, $linkmod_array, $extra_classes ); + shuffle( $classname_array ); + + // need a depth of 1 to ensure that our linkmods classes for inside dropdowns are also captured. + $depth = 1; + $returned_array = $method_open->invokeArgs( $wp_bootstrap_navwalker, array( $classname_array, &$linkmod_classes, &$icon_classes, $depth ) ); + + // linkmod_classes NOT should be empty and returned_array should not. + $this->assertTrue( ( ! empty( $linkmod_classes ) && ! empty( $returned_array ) ), 'Either the linkmod array of the returned non matching classes array is empty when they shoud not be.' ); + // starting arrays should no longer be empty. + $this->assertNotTrue( empty( $icon_classes ), 'Did not catch any icons.' ); + $this->assertNotTrue( empty( $linkmod_classes ), 'Did not catch any linkmods.' ); + + // icons compair. + $this->assertTrue( count( $icons_array ) === count( $icon_classes ), "Seems that icon classes are not catptured properly... valid: \n" . print_r( $icons_array, true ) . "returned: \n" . print_r( $icon_classes, true ) ); + $icon_differences = array_diff( $icons_array, $icon_classes ); + $this->assertTrue( empty( $icon_differences ), 'Seems that we did not catch all of the icon classes.' ); + // linkmod compair. + $this->assertTrue( count( $linkmod_array ) === count( $linkmod_classes ), "Seems that linkmod classes are not catptured properly... valid: \n" . print_r( $linkmod_array, true ) . "returned: \n" . print_r( $linkmod_classes, true ) ); + $linkmod_differences = array_diff( $icons_array, $icon_classes ); + $this->assertTrue( empty( $linkmod_differences ), 'Seems that we did not catch all of the linkmod classes.' ); + // extra classes string matches checks. + $returned_differences = array_diff( $returned_array, $extra_classes ); + $this->assertTrue( empty( $returned_differences ), 'The returned array minus the extra classes should be empty, likely some classes were missed or string malformation occured.' ); + + } + /** * Test get_linkmod_type Function exists. * @@ -274,6 +558,13 @@ function test_linkmod_element_close_function_exists() { } + /** + * Tests for valid markup being used as the opener and closer sections for + * some different linkmod types. + * + * @access public + * @return void + */ function test_linkmod_elements_open_and_close_successfully() { $wp_bootstrap_navwalker = $this->walker; From 1ac8e4dde7e08be20295ffd3ab56506febbf2587 Mon Sep 17 00:00:00 2001 From: William Patton Date: Thu, 22 Feb 2018 14:19:18 +0000 Subject: [PATCH 03/11] Use more accurate regex for matching icon and linkmod classnames --- CHANGELOG.md | 1 + class-wp-bootstrap-navwalker.php | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc954bf..5aec810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ #CHANGELOG ## [4.0.2] - Fix dropdown opener having empty string for href value. +- More accurate regex matching of icon and linkmod classnames. ## [4.0.1] - Fix untranslated string in fallback (this was lost in transition between v3 and v4, fixed again). diff --git a/class-wp-bootstrap-navwalker.php b/class-wp-bootstrap-navwalker.php index 311f90e..f3d2ef9 100644 --- a/class-wp-bootstrap-navwalker.php +++ b/class-wp-bootstrap-navwalker.php @@ -403,20 +403,20 @@ private function seporate_linkmods_and_icons_from_classes( $classes, &$linkmod_c foreach ( $classes as $key => $class ) { // If any special classes are found, store the class in it's // holder array and and unset the item from $classes. - if ( preg_match( '/disabled|sr-only/', $class ) ) { + if ( preg_match( '/^disabled|^sr-only/', $class ) ) { // Test for .disabled or .sr-only classes. $linkmod_classes[] = $class; unset( $classes[ $key ] ); - } elseif ( preg_match( '/dropdown-header|dropdown-divider/', $class ) && $depth > 0 ) { + } elseif ( preg_match( '/^dropdown-header|^dropdown-divider/', $class ) && $depth > 0 ) { // Test for .dropdown-header or .dropdown-divider and a // depth greater than 0 - IE inside a dropdown. $linkmod_classes[] = $class; unset( $classes[ $key ] ); - } elseif ( preg_match( '/fa-(\S*)?|fas(\s?)|far(\s?)|fal(\s?)|fab(\s?)|fa(\s?)/', $class ) ) { + } elseif ( preg_match( '/^fa-(\S*)?|^fa(s|r|l|b)?(\s?)?$/', $class ) ) { // Font Awesome. $icon_classes[] = $class; unset( $classes[ $key ] ); - } elseif ( preg_match( '/glyphicons-(\S*)?|glyphicons(\s?)/', $class ) ) { + } elseif ( preg_match( '/^glyphicon-(\S*)?|^glyphicon(\s?)$/', $class ) ) { // Glyphicons. $icon_classes[] = $class; unset( $classes[ $key ] ); From 8743bf97c7ab3e22156167c8f38b63c05d8c44f5 Mon Sep 17 00:00:00 2001 From: William Patton Date: Thu, 22 Feb 2018 14:31:48 +0000 Subject: [PATCH 04/11] Set package type to be library again this was lost in version swap from v3-v4 --- CHANGELOG.md | 1 + composer.json | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aec810..e84eedf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [4.0.2] - Fix dropdown opener having empty string for href value. - More accurate regex matching of icon and linkmod classnames. +- Changed composer package type to `library` from `wordpress-plugin` again. ## [4.0.1] - Fix untranslated string in fallback (this was lost in transition between v3 and v4, fixed again). diff --git a/composer.json b/composer.json index a58a514..b1f64dc 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "wp-bootstrap/wp-bootstrap-navwalker", "description": "A custom WordPress nav walker class to fully implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager.", - "type": "wordpress-plugin", + "type": "library", "license": "GPL-3.0+", "authors": [ { @@ -16,6 +16,9 @@ "issues": "https://github.com/wp-bootstrap/wp-bootstrap-navwalker/issues/", "source": "https://github.com/wp-bootstrap/wp-bootstrap-navwalker/" }, + "autoload": { + "files": ["class-wp-bootstrap-navwalker.php"] + }, "require": { "composer/installers": "~1.0" }, From 2c7c73b63d3290fdcccab5e1b689362c9452627a Mon Sep 17 00:00:00 2001 From: William Patton Date: Thu, 22 Feb 2018 14:37:32 +0000 Subject: [PATCH 05/11] Version bumber to 4.0.2 --- CHANGELOG.md | 1 + class-wp-bootstrap-navwalker.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e84eedf..edfece7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Fix dropdown opener having empty string for href value. - More accurate regex matching of icon and linkmod classnames. - Changed composer package type to `library` from `wordpress-plugin` again. +- Tests: Add unit tests for the function that separates classnames for the walker. ## [4.0.1] - Fix untranslated string in fallback (this was lost in transition between v3 and v4, fixed again). diff --git a/class-wp-bootstrap-navwalker.php b/class-wp-bootstrap-navwalker.php index f3d2ef9..d75c5fa 100644 --- a/class-wp-bootstrap-navwalker.php +++ b/class-wp-bootstrap-navwalker.php @@ -11,7 +11,7 @@ * Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker * Description: A custom WordPress nav walker class to implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager. * Author: Edward McIntyre - @twittem, WP Bootstrap, William Patton - @pattonwebz - * Version: 4.0.2-dev + * Version: 4.0.2 * Author URI: https://github.com/wp-bootstrap * GitHub Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker * GitHub Branch: master From ccd04391f8f2653b97ed4ec02dd9fd1d86e6f150 Mon Sep 17 00:00:00 2001 From: William Patton Date: Thu, 22 Feb 2018 14:39:42 +0000 Subject: [PATCH 06/11] Add php 7.1 & 7.2 to travis tests and drop the 5.3 multisite test --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 996f521..c3c7eca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,8 @@ branches: php: - 5.6 - 7.0 + - 7.1 + - 7.2 - nightly env: @@ -24,9 +26,6 @@ matrix: - dist: precise php: 5.3 env: WP_VERSION=latest WP_MULTISITE=0 - - dist: precise - php: 5.3 - env: WP_VERSION=latest WP_MULTISITE=1 allow_failures: - php: nightly From 562dbc03657771efe94bffcc3c0cfbce28fce117 Mon Sep 17 00:00:00 2001 From: William Patton Date: Thu, 22 Feb 2018 14:46:46 +0000 Subject: [PATCH 07/11] Fix PHPCS closing comment nags --- class-wp-bootstrap-navwalker.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/class-wp-bootstrap-navwalker.php b/class-wp-bootstrap-navwalker.php index d75c5fa..70c6909 100644 --- a/class-wp-bootstrap-navwalker.php +++ b/class-wp-bootstrap-navwalker.php @@ -377,7 +377,7 @@ public static function fallback( $args ) { } else { return $fallback_output; } - } // End if(). + } } /** @@ -550,4 +550,4 @@ private function linkmod_element_close( $linkmod_type ) { return $output; } } -} // End if(). +} From 5b86a392a1b97f2e2f2cff72cd3e34cd436506cf Mon Sep 17 00:00:00 2001 From: William Patton Date: Thu, 22 Feb 2018 16:17:53 +0000 Subject: [PATCH 08/11] Fix a count() error in one of the unit tests --- tests/test-navwalker.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test-navwalker.php b/tests/test-navwalker.php index a5d4344..4714d15 100644 --- a/tests/test-navwalker.php +++ b/tests/test-navwalker.php @@ -399,10 +399,10 @@ function test_seporate_linkmods_and_icons_from_classes_linkmods() { // icon_classes should be empty. $this->assertTrue( empty( $icon_classes ) ); + $num_of_items_left = count( $this->valid_linkmod_classes ) - count( $linkmod_classes ) - count( $this->valid_linkmod_typeflags ); // the number of items inside updated array should match [what we started with - minus the linkmods for inside dropdowns]. - $this->assertTrue( - (bool) count( ( $this->valid_linkmod_classes ) === ( count( $linkmod_classes ) - count( $this->valid_linkmod_typeflags ) ) ), - "Seems that the linkmod classes are not catptured properly when outside of dropdowns... \nvalid: \n" . print_r( $this->valid_linkmod_classes, true ) . "\nreturned: \n" . print_r( $linkmod_classes, true ) . "\n" . count( $this->valid_linkmod_classes ) . ' ' . count( $linkmod_classes ) . ' ' . count( $this->valid_linkmod_typeflags ) ); + $this->assertNotTrue( (bool) $num_of_items_left, + "Seems that the linkmod classes are not catptured properly when outside of dropdowns... \nvalid: \n" . print_r( $this->valid_linkmod_classes, true ) . "\nreturned: \n" . print_r( $linkmod_classes, true ) ); // get the differences between the original classes and updated classes. $linkmod_differences = array_diff( $this->valid_linkmod_classes, $linkmod_classes, $this->valid_linkmod_typeflags ); From 96a0b43d15fcf924c189e47c121a7adb96072071 Mon Sep 17 00:00:00 2001 From: William Patton Date: Thu, 22 Feb 2018 18:18:05 +0000 Subject: [PATCH 09/11] Allow mixed cases for icon and linkmod class matchers --- CHANGELOG.md | 1 + class-wp-bootstrap-navwalker.php | 8 ++++---- tests/test-navwalker.php | 13 +++++++++++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edfece7..3be87d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - More accurate regex matching of icon and linkmod classnames. - Changed composer package type to `library` from `wordpress-plugin` again. - Tests: Add unit tests for the function that separates classnames for the walker. +- Fix case sensitive matching to now match mixes of upper and lower case. ## [4.0.1] - Fix untranslated string in fallback (this was lost in transition between v3 and v4, fixed again). diff --git a/class-wp-bootstrap-navwalker.php b/class-wp-bootstrap-navwalker.php index 70c6909..34b9578 100644 --- a/class-wp-bootstrap-navwalker.php +++ b/class-wp-bootstrap-navwalker.php @@ -403,20 +403,20 @@ private function seporate_linkmods_and_icons_from_classes( $classes, &$linkmod_c foreach ( $classes as $key => $class ) { // If any special classes are found, store the class in it's // holder array and and unset the item from $classes. - if ( preg_match( '/^disabled|^sr-only/', $class ) ) { + if ( preg_match( '/^disabled|^sr-only/i', $class ) ) { // Test for .disabled or .sr-only classes. $linkmod_classes[] = $class; unset( $classes[ $key ] ); - } elseif ( preg_match( '/^dropdown-header|^dropdown-divider/', $class ) && $depth > 0 ) { + } elseif ( preg_match( '/^dropdown-header|^dropdown-divider/i', $class ) && $depth > 0 ) { // Test for .dropdown-header or .dropdown-divider and a // depth greater than 0 - IE inside a dropdown. $linkmod_classes[] = $class; unset( $classes[ $key ] ); - } elseif ( preg_match( '/^fa-(\S*)?|^fa(s|r|l|b)?(\s?)?$/', $class ) ) { + } elseif ( preg_match( '/^fa-(\S*)?|^fa(s|r|l|b)?(\s?)?$/i', $class ) ) { // Font Awesome. $icon_classes[] = $class; unset( $classes[ $key ] ); - } elseif ( preg_match( '/^glyphicon-(\S*)?|^glyphicon(\s?)$/', $class ) ) { + } elseif ( preg_match( '/^glyphicon-(\S*)?|^glyphicon(\s?)$/i', $class ) ) { // Glyphicons. $icon_classes[] = $class; unset( $classes[ $key ] ); diff --git a/tests/test-navwalker.php b/tests/test-navwalker.php index 4714d15..7b7dcc9 100644 --- a/tests/test-navwalker.php +++ b/tests/test-navwalker.php @@ -46,7 +46,8 @@ function setUp() { 'sr-only', ) ); - // array of valid font-awesome icon class starters plus some randomly chosen icon classes. + // array of valid font-awesome icon class starters plus some randomly + // chosen icon classes and some variations of upper/lower case letters. $this->some_fontawesome_classes = array( 'fa', 'fas', @@ -58,9 +59,13 @@ function setUp() { 'fa-home', 'fa-bluetooth-b', 'fa-chess-rook', + 'fA-home', + 'Fa-HoMe', + 'fa-HomE', ); - // array of valid glyphicon icon class starters plus some randomly chosen icon classes. + // array of valid glyphicon icon class starters plus some randomly + // chosen icon classes and some variations of upper/lower case letters. $this->some_glyphicons_classes = array( 'glyphicon', 'glyphicon-asterisk', @@ -70,6 +75,10 @@ function setUp() { 'glyphicon-sd-video', 'glyphicon-subscript', 'glyphicon-grain', + 'Glyphicon-file', + 'Glyphicon-File', + 'glyphicon-File', + 'glYphiCon-fiLe', ); } From 76d36c9a8d168db2956df04f4395a6e213dbcf40 Mon Sep 17 00:00:00 2001 From: William Patton Date: Fri, 23 Feb 2018 16:09:25 +0000 Subject: [PATCH 10/11] Apply PHPCS fixes on the test script.. for reasons... --- tests/test-navwalker.php | 84 ++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/tests/test-navwalker.php b/tests/test-navwalker.php index 7b7dcc9..7fb49a2 100644 --- a/tests/test-navwalker.php +++ b/tests/test-navwalker.php @@ -3,6 +3,8 @@ * Class SampleTest * * @package Wp_Bootstrap_Navwalker + * + * phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_print_r -- used for returned failure messages to give some details. */ /** @@ -11,14 +13,13 @@ * @extends WP_UnitTestCase */ class Test_WP_Bootstrap_NavWalker extends WP_UnitTestCase { - /** * The setUp function. * * @access public * @return void */ - function setUp() { + public function setUp() { parent::setUp(); @@ -89,7 +90,7 @@ function setUp() { * @access public * @return void */ - function test_navwalker_file_exists() { + public function test_navwalker_file_exists() { $this->assertFileExists( 'class-wp-bootstrap-navwalker.php' ); } @@ -99,7 +100,7 @@ function test_navwalker_file_exists() { * @access public * @return void */ - function test_startlvl_function_exists() { + public function test_startlvl_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -116,7 +117,7 @@ function test_startlvl_function_exists() { * @access public * @return void */ - function test_start_el_function_exists() { + public function test_start_el_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -133,7 +134,7 @@ function test_start_el_function_exists() { * @access public * @return void */ - function test_display_element_function_exists() { + public function test_display_element_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -145,12 +146,12 @@ function test_display_element_function_exists() { } /** - * Test Fallback Function exists. + * Test Fallback function exists. * * @access public * @return void */ - function test_fallback_function_exists() { + public function test_fallback_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -167,10 +168,10 @@ function test_fallback_function_exists() { * Expects that for logged out users both echo and return requests should * produce empty strings. * - * @access public - * @return void + * @access public + * @return void */ - function test_fallback_function_output_loggedout() { + public function test_fallback_function_output_loggedout() { // default is to echo reults, buffer. ob_start(); @@ -203,9 +204,9 @@ function test_fallback_function_output_loggedout() { * requesting either a return or defaulting to echo. * * @access public - * @return void + * @return void */ - function test_fallback_function_output_loggedin() { + public function test_fallback_function_output_loggedin() { // make an admin user and set it to be the current user. $user_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); @@ -218,7 +219,7 @@ function test_fallback_function_output_loggedin() { // rudimentary content test - confirm it opens a div with 2 expected // values and ends by closing a div. - $match = ( preg_match('/^(
)(.*?)(<\/div>)$/', $fallback_output_echo ) ) ? true : false; + $match = ( preg_match( '/^(
)(.*?)(<\/div>)$/', $fallback_output_echo ) ) ? true : false; $this->assertTrue( $match, 'Fallback method seems to create unexpected html for logged in users in echo mode.' @@ -243,7 +244,7 @@ function test_fallback_function_output_loggedin() { * @access public * @return void */ - function test_seporate_linkmods_and_icons_from_classes_function_exists() { + public function test_seporate_linkmods_and_icons_from_classes_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -261,9 +262,9 @@ function test_seporate_linkmods_and_icons_from_classes_function_exists() { * @depends test_seporate_linkmods_and_icons_from_classes_function_exists * * @access public - * @return void + * @return void */ - function test_seporate_linkmods_and_icons_from_classes_fontawesome() { + public function test_seporate_linkmods_and_icons_from_classes_fontawesome() { $wp_bootstrap_navwalker = $this->walker; // since we're working with private methods we need to use a reflector. @@ -299,7 +300,7 @@ function test_seporate_linkmods_and_icons_from_classes_fontawesome() { // icon_classes should no longer be empty. $this->assertNotTrue( empty( $icon_classes ) ); // the number of items inside updated $icon_classes should match number of valids we started with. - $this->assertTrue( count( $this->some_fontawesome_classes ) === count( $icon_classes ), "Seems that glyphicons classes are not catptured properly... \nvalid: \n" . print_r( $this->some_fontawesome_classes, true ) . "\nreturned: \n" . print_r( $icon_classes, true ) ); + $this->assertTrue( count( $this->some_fontawesome_classes ) === count( $icon_classes ), "Seems that glyphicons classes are not catptured properly... \nvalid: \n" . print_r( $this->some_fontawesome_classes, true ) . "\nreturned: \n" . print_r( $icon_classes, true ) ); // get the differences between the original classes and updated classes. $icon_differences = array_diff( $this->some_fontawesome_classes, $icon_classes ); // should be no differences thus empty array, this being TRUE also means @@ -315,9 +316,9 @@ function test_seporate_linkmods_and_icons_from_classes_fontawesome() { * @depends test_seporate_linkmods_and_icons_from_classes_function_exists * * @access public - * @return void + * @return void */ - function test_seporate_linkmods_and_icons_from_classes_glyphicons() { + public function test_seporate_linkmods_and_icons_from_classes_glyphicons() { $wp_bootstrap_navwalker = $this->walker; // since we're working with private methods we need to use a reflector. @@ -353,7 +354,7 @@ function test_seporate_linkmods_and_icons_from_classes_glyphicons() { // icon_classes should no longer be empty. $this->assertNotTrue( empty( $icon_classes ) ); // the number of items inside updated $icon_classes should match number of valids we started with. - $this->assertTrue( count( $this->some_glyphicons_classes ) === count( $icon_classes ), "Seems that glyphicons classes are not catptured properly... \nvalid: \n" . print_r( $this->some_glyphicons_classes, true ) . "\nreturned: \n" . print_r( $icon_classes, true ) ); + $this->assertTrue( count( $this->some_glyphicons_classes ) === count( $icon_classes ), "Seems that glyphicons classes are not catptured properly... \nvalid: \n" . print_r( $this->some_glyphicons_classes, true ) . "\nreturned: \n" . print_r( $icon_classes, true ) ); // get the differences between the original classes and updated classes. $icon_differences = array_diff( $this->some_glyphicons_classes, $icon_classes ); // should be no differences thus empty array, this being TRUE also means @@ -369,9 +370,9 @@ function test_seporate_linkmods_and_icons_from_classes_glyphicons() { * @depends test_seporate_linkmods_and_icons_from_classes_function_exists * * @access public - * @return void + * @return void */ - function test_seporate_linkmods_and_icons_from_classes_linkmods() { + public function test_seporate_linkmods_and_icons_from_classes_linkmods() { $wp_bootstrap_navwalker = $this->walker; // since we're working with private methods we need to use a reflector. @@ -410,8 +411,10 @@ function test_seporate_linkmods_and_icons_from_classes_linkmods() { $num_of_items_left = count( $this->valid_linkmod_classes ) - count( $linkmod_classes ) - count( $this->valid_linkmod_typeflags ); // the number of items inside updated array should match [what we started with - minus the linkmods for inside dropdowns]. - $this->assertNotTrue( (bool) $num_of_items_left, - "Seems that the linkmod classes are not catptured properly when outside of dropdowns... \nvalid: \n" . print_r( $this->valid_linkmod_classes, true ) . "\nreturned: \n" . print_r( $linkmod_classes, true ) ); + $this->assertNotTrue( + (bool) $num_of_items_left, + "Seems that the linkmod classes are not catptured properly when outside of dropdowns... \nvalid: \n" . print_r( $this->valid_linkmod_classes, true ) . "\nreturned: \n" . print_r( $linkmod_classes, true ) + ); // get the differences between the original classes and updated classes. $linkmod_differences = array_diff( $this->valid_linkmod_classes, $linkmod_classes, $this->valid_linkmod_typeflags ); @@ -419,14 +422,13 @@ function test_seporate_linkmods_and_icons_from_classes_linkmods() { // that text was exact match in the updated array vs the original. $this->assertTrue( empty( $linkmod_differences ) ); - // repeat some of the above tests but this time with depth = 1 so that we catch classes intended for inside dropdowns. - $depth = 1; + $depth = 1; $linkmod_classes_d = array(); $icon_classes_d = array(); - $returned_array_d = $method_open->invokeArgs( $wp_bootstrap_navwalker, array( $linkmod_array, &$linkmod_classes_d, &$icon_classes_d, $depth ) ); + $returned_array_d = $method_open->invokeArgs( $wp_bootstrap_navwalker, array( $linkmod_array, &$linkmod_classes_d, &$icon_classes_d, $depth ) ); - $this->assertTrue( count( $this->valid_linkmod_classes ) === count( $linkmod_classes_d ), "Seems that the linkmod classes are not catptured properly when inside dropdowns... \nvalid: \n" . print_r( $this->valid_linkmod_classes, true ) . "\nreturned: \n" . print_r( $linkmod_classes, true ) ); + $this->assertTrue( count( $this->valid_linkmod_classes ) === count( $linkmod_classes_d ), "Seems that the linkmod classes are not catptured properly when inside dropdowns... \nvalid: \n" . print_r( $this->valid_linkmod_classes, true ) . "\nreturned: \n" . print_r( $linkmod_classes, true ) ); $linkmod_differences_d = array_diff( $this->valid_linkmod_classes, $linkmod_classes_d ); $this->assertTrue( empty( $linkmod_differences_d ), 'There are differences between the matched classnames and the valid classnames.' ); @@ -443,9 +445,9 @@ function test_seporate_linkmods_and_icons_from_classes_linkmods() { * @depends test_seporate_linkmods_and_icons_from_classes_linkmods * * @access public - * @return void + * @return void */ - function test_seporate_linkmods_and_icons_from_classes_fulltest() { + public function test_seporate_linkmods_and_icons_from_classes_fulltest() { $wp_bootstrap_navwalker = $this->walker; // since we're working with private methods we need to use a reflector. @@ -476,21 +478,21 @@ function test_seporate_linkmods_and_icons_from_classes_fulltest() { shuffle( $classname_array ); // need a depth of 1 to ensure that our linkmods classes for inside dropdowns are also captured. - $depth = 1; + $depth = 1; $returned_array = $method_open->invokeArgs( $wp_bootstrap_navwalker, array( $classname_array, &$linkmod_classes, &$icon_classes, $depth ) ); // linkmod_classes NOT should be empty and returned_array should not. - $this->assertTrue( ( ! empty( $linkmod_classes ) && ! empty( $returned_array ) ), 'Either the linkmod array of the returned non matching classes array is empty when they shoud not be.' ); + $this->assertTrue( ( ! empty( $linkmod_classes ) && ! empty( $returned_array ) ), 'Either the linkmod array or the returned non matching classes array is empty when they shoud not be.' ); // starting arrays should no longer be empty. $this->assertNotTrue( empty( $icon_classes ), 'Did not catch any icons.' ); $this->assertNotTrue( empty( $linkmod_classes ), 'Did not catch any linkmods.' ); // icons compair. - $this->assertTrue( count( $icons_array ) === count( $icon_classes ), "Seems that icon classes are not catptured properly... valid: \n" . print_r( $icons_array, true ) . "returned: \n" . print_r( $icon_classes, true ) ); + $this->assertTrue( count( $icons_array ) === count( $icon_classes ), "Seems that icon classes are not catptured properly... valid: \n" . print_r( $icons_array, true ) . "returned: \n" . print_r( $icon_classes, true ) ); $icon_differences = array_diff( $icons_array, $icon_classes ); $this->assertTrue( empty( $icon_differences ), 'Seems that we did not catch all of the icon classes.' ); // linkmod compair. - $this->assertTrue( count( $linkmod_array ) === count( $linkmod_classes ), "Seems that linkmod classes are not catptured properly... valid: \n" . print_r( $linkmod_array, true ) . "returned: \n" . print_r( $linkmod_classes, true ) ); + $this->assertTrue( count( $linkmod_array ) === count( $linkmod_classes ), "Seems that linkmod classes are not catptured properly... valid: \n" . print_r( $linkmod_array, true ) . "returned: \n" . print_r( $linkmod_classes, true ) ); $linkmod_differences = array_diff( $icons_array, $icon_classes ); $this->assertTrue( empty( $linkmod_differences ), 'Seems that we did not catch all of the linkmod classes.' ); // extra classes string matches checks. @@ -505,7 +507,7 @@ function test_seporate_linkmods_and_icons_from_classes_fulltest() { * @access public * @return void */ - function test_get_linkmod_type_function_exists() { + public function test_get_linkmod_type_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -522,7 +524,7 @@ function test_get_linkmod_type_function_exists() { * @access public * @return void */ - function test_update_atts_for_linkmod_type_function_exists() { + public function test_update_atts_for_linkmod_type_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -539,7 +541,7 @@ function test_update_atts_for_linkmod_type_function_exists() { * @access public * @return void */ - function test_linkmod_element_open_function_exists() { + public function test_linkmod_element_open_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -556,7 +558,7 @@ function test_linkmod_element_open_function_exists() { * @access public * @return void */ - function test_linkmod_element_close_function_exists() { + public function test_linkmod_element_close_function_exists() { $wp_bootstrap_navwalker = $this->walker; @@ -572,9 +574,9 @@ function test_linkmod_element_close_function_exists() { * some different linkmod types. * * @access public - * @return void + * @return void */ - function test_linkmod_elements_open_and_close_successfully() { + public function test_linkmod_elements_open_and_close_successfully() { $wp_bootstrap_navwalker = $this->walker; From 815eefe300b8ab4da6c50b5605c391e99e958a69 Mon Sep 17 00:00:00 2001 From: William Patton Date: Sun, 25 Feb 2018 23:12:07 +0000 Subject: [PATCH 11/11] Convert tabs to spaces --- composer.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index b1f64dc..40607c5 100644 --- a/composer.json +++ b/composer.json @@ -7,18 +7,18 @@ { "name": "Brandon Hubbard" }, - { - "name": "William Patton", - "email": "will@pattonwebz.com" - } + { + "name": "William Patton", + "email": "will@pattonwebz.com" + } ], "support": { "issues": "https://github.com/wp-bootstrap/wp-bootstrap-navwalker/issues/", "source": "https://github.com/wp-bootstrap/wp-bootstrap-navwalker/" }, - "autoload": { - "files": ["class-wp-bootstrap-navwalker.php"] - }, + "autoload": { + "files": ["class-wp-bootstrap-navwalker.php"] + }, "require": { "composer/installers": "~1.0" },