1<?php 2 3namespace dokuwiki\plugin\struct\test\types; 4 5use dokuwiki\plugin\struct\meta\ValidationException; 6use dokuwiki\plugin\struct\meta\Value; 7use dokuwiki\plugin\struct\test\mock\Search; 8use dokuwiki\plugin\struct\test\StructTest; 9use dokuwiki\plugin\struct\types\Decimal; 10 11/** 12 * Testing the Decimal Type 13 * 14 * @group plugin_struct 15 * @group plugins 16 */ 17class DecimalTest extends StructTest 18{ 19 20 /** 21 * Provides failing min/max validation data 22 * 23 * @return array 24 */ 25 public function validateFailProvider() 26 { 27 return [ 28 // same as integer: 29 ['foo', '', ''], 30 ['foo222', '', ''], 31 ['-5', '0', ''], 32 ['5', '', '0'], 33 ['500', '100', '200'], 34 ['50', '100', '200'], 35 // decimal specifics 36 ['5.5', '5.6', ''], 37 ['5,5', '5.6', ''], 38 ['-5.5', '-5.4', ''], 39 ['-5,5', '-5.4', ''], 40 ]; 41 } 42 43 /** 44 * Provides successful min/max validation data 45 * 46 * @return array 47 */ 48 public function validateSuccessProvider() 49 { 50 return [ 51 // same as integer 52 ['0', '', ''], 53 ['-5', '', ''], 54 ['5', '', ''], 55 ['5', '0', ''], 56 ['-5', '', '0'], 57 ['150', '100', '200'], 58 // decimal specifics 59 ['5.5', '', ''], 60 ['5,5', '', ''], 61 ['-5.5', '', ''], 62 ['-5,5', '', ''], 63 ['5.5', '4.5', ''], 64 ['5,5', '4.5', ''], 65 ['-5.5', '', '4.5'], 66 ['-5,5', '', '4.5'], 67 ['5.5645000', '', ''], 68 // boundaries 69 ['0', '0', ''], 70 ['0', '', '0'], 71 ['5', '5', ''], 72 ['5', '', '5'], 73 ['0', '0.0', ''], 74 ['0', '', '0.0'], 75 ['5.0', '5.0', ''], 76 ['5.0', '', '5.0'], 77 ]; 78 } 79 80 81 /** 82 * @dataProvider validateFailProvider 83 */ 84 public function test_validate_fail($value, $min, $max) 85 { 86 $this->expectException(ValidationException::class); 87 $decimal = new Decimal(array('min' => $min, 'max' => $max)); 88 $decimal->validate($value); 89 } 90 91 /** 92 * @dataProvider validateSuccessProvider 93 */ 94 public function test_validate_success($value, $min, $max, $decpoint = '.') 95 { 96 $decimal = new Decimal(array('min' => $min, 'max' => $max)); 97 $decimal->validate($value); 98 $this->assertTrue(true); // we simply check that no exceptions are thrown 99 } 100 101 102 public function valueProvider() 103 { 104 return [ 105 // $value, $expect, $roundto, $decpoint, $thousands, $trimzeros, $prefix='', $postfix='', $engineering = false 106 ['5000', '5 000,00', '2', ',', ' ', false], 107 ['5000', '5 000', '2', ',', ' ', true], 108 ['5000', '5 000', '0', ',', ' ', false], 109 ['5000', '5 000', '0', ',', ' ', true], 110 ['5000', '5 000', '', ',', ' ', false], 111 ['5000', '5 000', '', ',', ' ', true], 112 ['5000', '5 000', '-1', ',', ' ', false], 113 ['5000', '5 000', '-1', ',', ' ', true], 114 115 ['777.707', '778', '0', ',', ' ', true], 116 ['777.707', '778', '', ',', ' ', true], 117 ['777.707', '777,71', '2', ',', ' ', true], 118 ['777.707', '777,71', '2', ',', ' ', false], 119 120 ['-0.55600', '-0,56', '2', ',', ' ', false], 121 ['-0.55600', '-0,55600', '-1', ',', ' ', false], 122 ['-0.55600', '-0,556', '-1', ',', ' ', true], 123 ['-0.55600', '-0,5560', '4', ',', ' ', false], 124 ['-0.55600', '-0,556', '4', ',', ' ', true], 125 126 ['-0.55600', '$ -0,556', '4', ',', ' ', true, '$ '], 127 ['-0.55600', '-0,556 EUR', '4', ',', ' ', true, '', ' EUR'], 128 129 //engineering notation 130 ['1e-18', '1' . "\xE2\x80\xAF" . 'a', '-1', ',', ' ', true, '', '', true], 131 ['1e-15', '1' . "\xE2\x80\xAF" . 'f', '-1', ',', ' ', true, '', '', true], 132 ['1e-12', '1' . "\xE2\x80\xAF" . 'p', '-1', ',', ' ', true, '', '', true], 133 ['1e-9', '1' . "\xE2\x80\xAF" . 'n', '-1', ',', ' ', true, '', '', true], 134 ['1e-6', '1' . "\xE2\x80\xAF" . 'µ', '-1', ',', ' ', true, '', '', true], 135 ['1e-3', '1' . "\xE2\x80\xAF" . 'm', '-1', ',', ' ', true, '', '', true], 136 137 ['1e3', '1' . "\xE2\x80\xAF" . 'k', '-1', ',', ' ', true, '', '', true], 138 ['1e6', '1' . "\xE2\x80\xAF" . 'M', '-1', ',', ' ', true, '', '', true], 139 ['1e9', '1' . "\xE2\x80\xAF" . 'G', '-1', ',', ' ', true, '', '', true], 140 ['1e12', '1' . "\xE2\x80\xAF" . 'T', '-1', ',', ' ', true, '', '', true], 141 142 ['1e4', '10' . "\xE2\x80\xAF" . 'k', '-1', ',', ' ', true, '', '', true], 143 ['1e5', '100' . "\xE2\x80\xAF" . 'k', '-1', ',', ' ', true, '', '', true], 144 145 ['1e-4', '100' . "\xE2\x80\xAF" . 'µ', '-1', ',', ' ', true, '', '', true], 146 ['1e-5', '10' . "\xE2\x80\xAF" . 'µ', '-1', ',', ' ', true, '', '', true], 147 148 //test behaviour if number exceeds prefix array 149 ['1e15', '1000' . "\xE2\x80\xAF" . 'T', '-1', ',', ' ', true, '', '', true], 150 ['1e-21', '0.001' . "\xE2\x80\xAF" . 'a', '-1', ',', ' ', true, '', '', true], 151 152 ]; 153 } 154 155 /** 156 * @dataProvider valueProvider 157 */ 158 public function test_renderValue( 159 $value, $expect, $roundto, $decpoint, 160 $thousands, $trimzeros, 161 $prefix = '', $postfix = '', $engineering = false 162 ) 163 { 164 $decimal = new Decimal([ 165 'roundto' => $roundto, 166 'decpoint' => $decpoint, 167 'thousands' => $thousands, 168 'trimzeros' => $trimzeros, 169 'prefix' => $prefix, 170 'postfix' => $postfix, 171 'engineering' => $engineering 172 ]); 173 $R = new \Doku_Renderer_xhtml(); 174 $R->doc = ''; 175 $decimal->renderValue($value, $R, 'xhtml'); 176 $this->assertEquals($expect, $R->doc); 177 } 178 179 public function test_sort() 180 { 181 $this->loadSchemaJSON('decimal'); 182 $this->waitForTick(); 183 $this->saveData('page1', 'decimal', ['field' => '5000']); 184 $this->saveData('page2', 'decimal', ['field' => '5000.001']); 185 $this->saveData('page3', 'decimal', ['field' => '900.5']); 186 $this->saveData('page4', 'decimal', ['field' => '1.5']); 187 188 $search = new Search(); 189 $search->addSchema('decimal'); 190 $search->addColumn('%pageid%'); 191 $search->addColumn('field'); 192 $search->addSort('field', true); 193 /** @var Value[][] $result */ 194 $result = $search->getRows(); 195 196 $this->assertEquals(4, count($result)); 197 $this->assertEquals('page4', $result[0][0]->getValue()); 198 $this->assertEquals('page3', $result[1][0]->getValue()); 199 $this->assertEquals('page1', $result[2][0]->getValue()); 200 $this->assertEquals('page2', $result[3][0]->getValue()); 201 } 202 203 public function test_filter() 204 { 205 $this->loadSchemaJSON('decimal'); 206 $this->waitForTick(); 207 $this->saveData('page1', 'decimal', ['field' => '5000']); 208 $this->saveData('page2', 'decimal', ['field' => '5000.001']); 209 $this->saveData('page3', 'decimal', ['field' => '900.5']); 210 $this->saveData('page4', 'decimal', ['field' => '1.5']); 211 212 $search = new Search(); 213 $search->addSchema('decimal'); 214 $search->addColumn('%pageid%'); 215 $search->addColumn('field'); 216 $search->addFilter('field', '800', '>', 'AND'); 217 $search->addSort('field', true); 218 /** @var Value[][] $result */ 219 $result = $search->getRows(); 220 221 $this->assertEquals(3, count($result)); 222 $this->assertEquals('page3', $result[0][0]->getValue()); 223 $this->assertEquals('page1', $result[1][0]->getValue()); 224 $this->assertEquals('page2', $result[2][0]->getValue()); 225 } 226 227} 228