1<?php 2/** 3 * Unit tests for HTML_QuickForm2 package 4 * 5 * PHP version 5 6 * 7 * LICENSE 8 * 9 * This source file is subject to BSD 3-Clause License that is bundled 10 * with this package in the file LICENSE and available at the URL 11 * https://raw.githubusercontent.com/pear/HTML_QuickForm2/trunk/docs/LICENSE 12 * 13 * @category HTML 14 * @package HTML_QuickForm2 15 * @author Alexey Borzov <avb@php.net> 16 * @author Bertrand Mansion <golgote@mamasam.com> 17 * @copyright 2006-2021 Alexey Borzov <avb@php.net>, Bertrand Mansion <golgote@mamasam.com> 18 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License 19 * @link https://pear.php.net/package/HTML_QuickForm2 20 */ 21 22/** Sets up includes */ 23require_once dirname(__DIR__) . '/TestHelper.php'; 24 25/** 26 * The non-abstract subclass of Rule 27 */ 28class HTML_QuickForm2_Rule_ImplConst extends HTML_QuickForm2_Rule 29{ 30 protected function validateOwner() 31 { 32 // It just returns whatever value was passed to setConfig() 33 return $this->config; 34 } 35} 36 37/** 38 * Unit test for HTML_QuickForm2_Rule class 39 */ 40class HTML_QuickForm2_RuleTest extends PHPUnit_Framework_TestCase 41{ 42 public function testSetAndGetOptions() 43 { 44 $rule = new HTML_QuickForm2_Rule_ImplConst( 45 new HTML_QuickForm2_Element_InputText('foo'), 'a message', 'bar' 46 ); 47 $this->assertEquals('bar', $rule->getConfig()); 48 49 $this->assertSame($rule, $rule->setConfig('baz')); 50 $this->assertEquals('baz', $rule->getConfig()); 51 } 52 53 public function testSetAndGetMessage() 54 { 55 $rule = new HTML_QuickForm2_Rule_ImplConst( 56 new HTML_QuickForm2_Element_InputText('foo'), 'a message', 'bar' 57 ); 58 $this->assertEquals('a message', $rule->getMessage()); 59 60 $this->assertSame($rule, $rule->setMessage('another message')); 61 $this->assertEquals('another message', $rule->getMessage()); 62 } 63 64 public function testValidateSingle() 65 { 66 $ruleTrue = new HTML_QuickForm2_Rule_ImplConst( 67 new HTML_QuickForm2_Element_InputText('ruleTrue'), 'a message', true 68 ); 69 $this->assertTrue($ruleTrue->validate()); 70 71 $ruleFalse = new HTML_QuickForm2_Rule_ImplConst( 72 new HTML_QuickForm2_Element_InputText('ruleFalse'), 'a message', false 73 ); 74 $this->assertFalse($ruleFalse->validate()); 75 } 76 77 public function testValidateChained() 78 { 79 $elTest = new HTML_QuickForm2_Element_InputText('testAndOr'); 80 $ruleAnd = new HTML_QuickForm2_Rule_ImplConst($elTest, 'a message', true); 81 $ruleAnd->and_(new HTML_QuickForm2_Rule_ImplConst($elTest, 'a message', false)); 82 $this->assertFalse($ruleAnd->validate()); 83 84 $ruleOr = new HTML_QuickForm2_Rule_ImplConst($elTest, 'a message', false); 85 $ruleOr->or_(new HTML_QuickForm2_Rule_ImplConst($elTest, 'a message', true)); 86 $this->assertTrue($ruleOr->validate()); 87 } 88 89 public function testOperatorPrecedence() 90 { 91 // true = true or true and false != ((true or true) and false) = false 92 $elTest = new HTML_QuickForm2_Element_InputText('testPrecedence'); 93 $ruleTrue = new HTML_QuickForm2_Rule_ImplConst($elTest, 'a message', true); 94 $ruleFalse = new HTML_QuickForm2_Rule_ImplConst($elTest, 'a message', false); 95 96 $ruleTrue->or_(clone $ruleTrue)->and_($ruleFalse); 97 $this->assertTrue($ruleTrue->validate()); 98 } 99 100 public function testShortCircuitedEvaluationAnd() 101 { 102 $elTest = new HTML_QuickForm2_Element_InputText('testShortCircuitedAnd'); 103 $ruleTrue = new HTML_QuickForm2_Rule_ImplConst($elTest, '...', true); 104 $ruleFalse = new HTML_QuickForm2_Rule_ImplConst($elTest, '...', false); 105 106 $ruleAndTrue = $this->getMockBuilder('HTML_QuickForm2_Rule') 107 ->setMethods(['validateOwner']) 108 ->setConstructorArgs([$elTest]) 109 ->getMock(); 110 $ruleAndTrue->expects($this->once())->method('validateOwner'); 111 $ruleTrue->and_($ruleAndTrue); 112 $ruleTrue->validate(); 113 114 $ruleAndFalse = $this->getMockBuilder('HTML_QuickForm2_Rule') 115 ->setMethods(['validateOwner']) 116 ->setConstructorArgs([$elTest]) 117 ->getMock(); 118 $ruleAndFalse->expects($this->never())->method('validateOwner'); 119 $ruleFalse->and_($ruleAndFalse); 120 $ruleFalse->validate(); 121 } 122 123 public function testShortCircuitedEvaluationOr() 124 { 125 $elTest = new HTML_QuickForm2_Element_InputText('testShortCircuitedOr'); 126 $ruleTrue = new HTML_QuickForm2_Rule_ImplConst($elTest, '...', true); 127 $ruleFalse = new HTML_QuickForm2_Rule_ImplConst($elTest, '...', false); 128 129 $ruleOrTrue = $this->getMockBuilder('HTML_QuickForm2_Rule') 130 ->setMethods(['validateOwner']) 131 ->setConstructorArgs([$elTest]) 132 ->getMock(); 133 $ruleOrTrue->expects($this->never())->method('validateOwner'); 134 $ruleTrue->or_($ruleOrTrue); 135 $ruleTrue->validate(); 136 137 $ruleOrFalse = $this->getMockBuilder('HTML_QuickForm2_Rule') 138 ->setMethods(['validateOwner']) 139 ->setConstructorArgs([$elTest]) 140 ->getMock(); 141 $ruleOrFalse->expects($this->once())->method('validateOwner'); 142 $ruleFalse->or_($ruleOrFalse); 143 $ruleFalse->validate(); 144 } 145 146 public function testSetErrorOnlyOnChainFailure() 147 { 148 $elTest = new HTML_QuickForm2_Element_InputText('valid'); 149 $chain = new HTML_QuickForm2_Rule_ImplConst($elTest, 'bogus error', false); 150 $chain->or_(new HTML_QuickForm2_Rule_ImplConst($elTest, '', true)); 151 152 $this->assertTrue($chain->validate()); 153 $this->assertEquals('', $elTest->getError()); 154 155 $chain2 = new HTML_QuickForm2_Rule_ImplConst($elTest, 'genuine error', false); 156 $chain2->or_(new HTML_QuickForm2_Rule_ImplConst($elTest, '', false)); 157 158 $this->assertFalse($chain2->validate()); 159 $this->assertEquals('genuine error', $elTest->getError()); 160 } 161 162 public function testDefaultConfigMerging() 163 { 164 $this->assertEquals('foo', HTML_QuickForm2_Rule::mergeConfig('foo', null)); 165 $this->assertEquals('bar', HTML_QuickForm2_Rule::mergeConfig('foo', 'bar')); 166 167 HTML_QuickForm2_Factory::registerRule('no-config', 'HTML_QuickForm2_Rule_ImplConst'); 168 HTML_QuickForm2_Factory::registerRule('with-config', 'HTML_QuickForm2_Rule_ImplConst', 169 null, 'bar'); 170 $el = new HTML_QuickForm2_Element_InputText(); 171 $this->assertEquals('foo', $el->createRule('no-config', '', 'foo')->getConfig()); 172 $this->assertEquals('bar', $el->createRule('with-config', '', 'foo')->getConfig()); 173 } 174 175 public function testValidationTriggers() 176 { 177 $el = new HTML_QuickForm2_Element_InputText('foo', ['id' => 'foo']); 178 $rule = $this->getMockBuilder('HTML_QuickForm2_Rule') 179 ->setMethods(['validateOwner', 'getJavascriptCallback']) 180 ->setConstructorArgs([$el]) 181 ->getMock(); 182 $rule->expects($this->any())->method('getJavascriptCallback') 183 ->will($this->returnValue('a callback')); 184 185 $this->assertContains('qf.LiveRule', $rule->getJavascript()); 186 $this->assertContains('["foo"]', $rule->getJavascript()); 187 $this->assertNotContains('qf.LiveRule', $rule->getJavascript(false)); 188 } 189 190 public function testChainedValidationTriggers() 191 { 192 $foo = new HTML_QuickForm2_Element_InputText('foo', ['id' => 'foo']); 193 $bar = new HTML_QuickForm2_Element_InputText('bar', ['id' => 'bar']); 194 $baz = new HTML_QuickForm2_Element_InputText('baz', ['id' => 'baz']); 195 196 $ruleFoo = $this->getMockBuilder('HTML_QuickForm2_Rule') 197 ->setMethods(['validateOwner', 'getJavascriptCallback']) 198 ->setConstructorArgs([$foo]) 199 ->getMock(); 200 $ruleBar = $this->getMockBuilder('HTML_QuickForm2_Rule') 201 ->setMethods(['validateOwner', 'getJavascriptCallback']) 202 ->setConstructorArgs([$bar]) 203 ->getMock(); 204 $ruleBaz = $this->getMockBuilder('HTML_QuickForm2_Rule') 205 ->setMethods(['validateOwner', 'getJavascriptCallback']) 206 ->setConstructorArgs([$baz]) 207 ->getMock(); 208 $ruleFoo->expects($this->once())->method('getJavascriptCallback') 209 ->will($this->returnValue('a callback')); 210 $ruleBar->expects($this->once())->method('getJavascriptCallback') 211 ->will($this->returnValue('a callback')); 212 $ruleBar->expects($this->once())->method('getJavascriptCallback') 213 ->will($this->returnValue('a callback')); 214 215 $script = $ruleFoo->and_($ruleBar->and_($ruleBaz))->getJavascript(); 216 preg_match('/\[\S+\]/', $script, $m); 217 $this->assertContains('foo', $m[0]); 218 $this->assertContains('bar', $m[0]); 219 $this->assertContains('baz', $m[0]); 220 } 221 222 public function testCannotSetErrorsOnHiddenElements() 223 { 224 $hidden = new HTML_QuickForm2_Element_InputHidden('noError'); 225 $text = new HTML_QuickForm2_Element_InputText('canHaveError'); 226 227 try { 228 $rule = $this->getMockBuilder('HTML_QuickForm2_Rule') 229 ->setMethods(['validateOwner']) 230 ->setConstructorArgs([$hidden, 'an error message']) 231 ->getMock(); 232 $this->fail('Expected HTML_QuickForm2_InvalidArgumentException was not thrown'); 233 } catch (HTML_QuickForm2_InvalidArgumentException $e) {} 234 235 try { 236 $rule = $this->getMockBuilder('HTML_QuickForm2_Rule') 237 ->setMethods(['validateOwner']) 238 ->setConstructorArgs([$text, 'an error message']) 239 ->getMock(); 240 $rule->setOwner($hidden); 241 $this->fail('Expected HTML_QuickForm2_InvalidArgumentException was not thrown'); 242 } catch (HTML_QuickForm2_InvalidArgumentException $e) {} 243 } 244} 245?> 246