1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
include_once __DIR__ . '/../lib/xmlrpc.inc'; |
4
|
|
|
include_once __DIR__ . '/../lib/xmlrpcs.inc'; |
5
|
|
|
|
6
|
|
|
include_once __DIR__ . '/parse_args.php'; |
7
|
|
|
|
8
|
|
|
include_once __DIR__ . '/PolyfillTestCase.php'; |
9
|
|
|
|
10
|
|
|
use PHPUnit\Runner\BaseTestRunner; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Tests involving the Value class. |
14
|
|
|
* NB: these tests do not involve the parsing of xml into Value objects - look in 03ParsingTest for that |
15
|
|
|
*/ |
16
|
|
|
class ValueTests extends PhpXmlRpc_PolyfillTestCase |
17
|
|
|
{ |
18
|
|
|
public $args = array(); |
19
|
|
|
|
20
|
|
|
protected function set_up() |
21
|
|
|
{ |
22
|
|
|
$this->args = argParser::getArgs(); |
23
|
|
|
if ($this->args['DEBUG'] == 1) |
24
|
|
|
ob_start(); |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
protected function tear_down() |
28
|
|
|
{ |
29
|
|
|
if ($this->args['DEBUG'] != 1) |
30
|
|
|
return; |
31
|
|
|
$out = ob_get_clean(); |
32
|
|
|
$status = $this->getStatus(); |
33
|
|
|
if ($status == BaseTestRunner::STATUS_ERROR |
34
|
|
|
|| $status == BaseTestRunner::STATUS_FAILURE) { |
35
|
|
|
echo $out; |
36
|
|
|
} |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
public function testMinusOneString() |
40
|
|
|
{ |
41
|
|
|
$v = new xmlrpcval('-1'); |
42
|
|
|
$u = new xmlrpcval('-1', 'string'); |
43
|
|
|
$t = new xmlrpcval(-1, 'string'); |
44
|
|
|
$this->assertEquals($v->scalarval(), $u->scalarval()); |
45
|
|
|
$this->assertEquals($v->scalarval(), $t->scalarval()); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* This looks funny, and we might call it a bug. But we strive for 100 backwards compat... |
50
|
|
|
*/ |
51
|
|
|
public function testMinusOneInt() |
52
|
|
|
{ |
53
|
|
|
$u = new xmlrpcval(); |
54
|
|
|
$v = new xmlrpcval(-1); |
55
|
|
|
$this->assertEquals($u->scalarval(), $v->scalarval()); |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
public function testAddScalarToStruct() |
59
|
|
|
{ |
60
|
|
|
$v = new xmlrpcval(array('a' => 'b'), 'struct'); |
61
|
|
|
// use @ operator in case error_log gets on screen |
62
|
|
|
$r = @$v->addscalar('c'); |
63
|
|
|
$this->assertEquals(0, $r); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
public function testAddStructToStruct() |
67
|
|
|
{ |
68
|
|
|
$v = new xmlrpcval(array('a' => new xmlrpcval('b')), 'struct'); |
69
|
|
|
$r = $v->addstruct(array('b' => new xmlrpcval('c'))); |
70
|
|
|
$this->assertEquals(2, $v->structsize()); |
|
|
|
|
71
|
|
|
$this->assertEquals(1, $r); |
72
|
|
|
$r = $v->addstruct(array('b' => new xmlrpcval('b'))); |
|
|
|
|
73
|
|
|
$this->assertEquals(2, $v->structsize()); |
|
|
|
|
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
public function testAddArrayToArray() |
77
|
|
|
{ |
78
|
|
|
$v = new xmlrpcval(array(new xmlrpcval('a'), new xmlrpcval('b')), 'array'); |
79
|
|
|
$r = $v->addarray(array(new xmlrpcval('b'), new xmlrpcval('c'))); |
80
|
|
|
$this->assertEquals(4, $v->arraysize()); |
|
|
|
|
81
|
|
|
$this->assertEquals(1, $r); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/// @todo does this test check something useful at all? |
85
|
|
|
public function testUTF8IntString() |
86
|
|
|
{ |
87
|
|
|
$v = new xmlrpcval(100, 'int'); |
88
|
|
|
$s = $v->serialize('UTF-8'); |
89
|
|
|
$this->assertequals("<value><int>100</int></value>\n", $s); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
public function testUTF8String() |
93
|
|
|
{ |
94
|
|
|
$sendstring = 'κόσμε'; // Greek word 'kosme' |
95
|
|
|
$GLOBALS['xmlrpc_internalencoding'] = 'UTF-8'; |
96
|
|
|
\PhpXmlRpc\PhpXmlRpc::importGlobals(); |
97
|
|
|
$f = new xmlrpcval($sendstring, 'string'); |
98
|
|
|
$v = $f->serialize(); |
99
|
|
|
$this->assertEquals("<value><string>κόσμε</string></value>\n", $v); |
100
|
|
|
$v = $f->serialize('UTF-8'); |
101
|
|
|
$this->assertEquals("<value><string>$sendstring</string></value>\n", $v); |
102
|
|
|
$GLOBALS['xmlrpc_internalencoding'] = 'ISO-8859-1'; |
103
|
|
|
\PhpXmlRpc\PhpXmlRpc::importGlobals(); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
public function testStringInt() |
107
|
|
|
{ |
108
|
|
|
$v = new xmlrpcval('hello world', 'int'); |
109
|
|
|
$s = $v->serialize(); |
110
|
|
|
$this->assertequals("<value><int>0</int></value>\n", $s); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
public function testDate() |
114
|
|
|
{ |
115
|
|
|
$tz = date_default_timezone_get(); |
116
|
|
|
date_default_timezone_set('UTC'); |
117
|
|
|
|
118
|
|
|
$ts = 86401; |
119
|
|
|
$dt = new DateTime('@86401'); |
120
|
|
|
|
121
|
|
|
$v = new xmlrpcval(86401, 'dateTime.iso8601'); |
122
|
|
|
$s = $v->serialize(); |
123
|
|
|
$this->assertequals("<value><dateTime.iso8601>19700102T00:00:01</dateTime.iso8601></value>\n", $s); |
124
|
|
|
|
125
|
|
|
$v = new xmlrpcval($dt, 'dateTime.iso8601'); |
126
|
|
|
$s = $v->serialize(); |
127
|
|
|
$this->assertequals("<value><dateTime.iso8601>19700102T00:00:01</dateTime.iso8601></value>\n", $s); |
128
|
|
|
|
129
|
|
|
$v = new xmlrpcval(\PhpXmlRpc\Helper\Date::iso8601Encode($ts), 'dateTime.iso8601'); |
130
|
|
|
$s = $v->serialize(); |
131
|
|
|
$this->assertequals("<value><dateTime.iso8601>19700102T00:00:01</dateTime.iso8601></value>\n", $s); |
132
|
|
|
|
133
|
|
|
$v = new xmlrpcval(\PhpXmlRpc\Helper\Date::iso8601Encode($dt), 'dateTime.iso8601'); |
134
|
|
|
$s = $v->serialize(); |
135
|
|
|
$this->assertequals("<value><dateTime.iso8601>19700102T00:00:01</dateTime.iso8601></value>\n", $s); |
136
|
|
|
|
137
|
|
|
date_default_timezone_set($tz); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/// @todo is this included in the above? |
141
|
|
|
public function testDateTime() |
142
|
|
|
{ |
143
|
|
|
$time = time(); |
144
|
|
|
$t1 = new xmlrpcval($time, 'dateTime.iso8601'); |
145
|
|
|
$t2 = new xmlrpcval(iso8601_encode($time), 'dateTime.iso8601'); |
146
|
|
|
$this->assertEquals($t1->serialize(), $t2->serialize()); |
147
|
|
|
$datetime = new DateTime(); |
148
|
|
|
$t3 = new xmlrpcval($datetime->setTimestamp($time), 'dateTime.iso8601'); |
149
|
|
|
$this->assertEquals($t1->serialize(), $t3->serialize()); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
public function testStructMemExists() |
153
|
|
|
{ |
154
|
|
|
$v = new xmlrpcval(array('hello' => new xmlrpcval('world')), 'struct'); |
155
|
|
|
$b = $v->structmemexists('hello'); |
|
|
|
|
156
|
|
|
$this->assertequals(true, $b); |
157
|
|
|
$b = $v->structmemexists('world'); |
|
|
|
|
158
|
|
|
$this->assertequals(false, $b); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
public function testLocale() |
162
|
|
|
{ |
163
|
|
|
$locale = setlocale(LC_NUMERIC, 0); |
164
|
|
|
/// @todo on php 5.3/win setting locale to german does not seem to set decimal separator to comma... |
165
|
|
|
if (setlocale(LC_NUMERIC, 'deu', 'de_DE@euro', 'de_DE', 'de', 'ge') !== false) { |
166
|
|
|
$v = new xmlrpcval(1.1, 'double'); |
167
|
|
|
if (strpos($v->scalarval(), ',') == 1) { |
168
|
|
|
$r = $v->serialize(); |
169
|
|
|
$this->assertequals(false, strpos($r, ',')); |
170
|
|
|
setlocale(LC_NUMERIC, $locale); |
171
|
|
|
} else { |
172
|
|
|
setlocale(LC_NUMERIC, $locale); |
173
|
|
|
$this->markTestSkipped('did not find a locale which sets decimal separator to comma'); |
174
|
|
|
} |
175
|
|
|
} else { |
176
|
|
|
$this->markTestSkipped('did not find a locale which sets decimal separator to comma'); |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
public function testArrayAccess() |
181
|
|
|
{ |
182
|
|
|
$v1 = new xmlrpcval(array(new xmlrpcval('one'), new xmlrpcval('two')), 'array'); |
183
|
|
|
$this->assertequals(1, count($v1)); |
184
|
|
|
$out = array('me' => array(), 'mytype' => 2, '_php_class' => null); |
185
|
|
|
|
186
|
|
|
foreach($v1 as $key => $val) |
187
|
|
|
{ |
188
|
|
|
$this->assertArrayHasKey($key, $out); |
189
|
|
|
$expected = $out[$key]; |
190
|
|
|
if (gettype($expected) == 'array') { |
191
|
|
|
$this->assertequals('array', gettype($val)); |
192
|
|
|
} else { |
193
|
|
|
$this->assertequals($expected, $val); |
194
|
|
|
} |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
$v2 = new \PhpXmlRpc\Value(array(new \PhpXmlRpc\Value('one'), new \PhpXmlRpc\Value('two')), 'array'); |
198
|
|
|
$this->assertequals(2, count($v2)); |
199
|
|
|
$out = array(array('key' => 0, 'value' => 'object'), array('key' => 1, 'value' => 'object')); |
200
|
|
|
$i = 0; |
201
|
|
|
foreach($v2 as $key => $val) |
202
|
|
|
{ |
203
|
|
|
$expected = $out[$i]; |
204
|
|
|
$this->assertequals($expected['key'], $key); |
205
|
|
|
$this->assertequals($expected['value'], gettype($val)); |
206
|
|
|
$i++; |
207
|
|
|
} |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/// @todo do not use \PhpXmlRpc\Encoder for this test |
211
|
|
|
public function testBigXML() |
212
|
|
|
{ |
213
|
|
|
// nb: make sure that the serialized xml corresponding to this is > 10MB in size |
214
|
|
|
$data = array(); |
215
|
|
|
for ($i = 0; $i < 500000; $i++ ) { |
216
|
|
|
$data[] = 'hello world'; |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
$encoder = new \PhpXmlRpc\Encoder(); |
220
|
|
|
$val = $encoder->encode($data); |
221
|
|
|
$req = new \PhpXmlRpc\Request('test', array($val)); |
222
|
|
|
$xml = $req->serialize(); |
223
|
|
|
$parser = new \PhpXmlRpc\Helper\XMLParser(); |
224
|
|
|
$parser->parse($xml); |
225
|
|
|
|
226
|
|
|
$this->assertequals(0, $parser->_xh['isf']); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
public function testLatin15InternalEncoding() |
230
|
|
|
{ |
231
|
|
|
if (!function_exists('mb_convert_encoding')) { |
232
|
|
|
$this->markTestSkipped('Miss mbstring extension to test exotic charsets'); |
233
|
|
|
return; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
$string = chr(164); |
237
|
|
|
$v = new \PhpXmlRpc\Value($string); |
238
|
|
|
|
239
|
|
|
$originalEncoding = \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding; |
240
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = 'ISO-8859-15'; |
241
|
|
|
|
242
|
|
|
$this->assertEquals("<value><string>€</string></value>", trim($v->serialize('US-ASCII'))); |
243
|
|
|
$this->assertEquals("<value><string>$string</string></value>", trim($v->serialize('ISO-8859-15'))); |
244
|
|
|
$this->assertEquals("<value><string>€</string></value>", trim($v->serialize('UTF-8'))); |
245
|
|
|
|
246
|
|
|
\PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding = $originalEncoding; |
247
|
|
|
} |
248
|
|
|
} |
249
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.