9ec5796dd32dd92ea470cb643c61addb9feca217
[lhc/web/wiklou.git] / tests / phpunit / includes / media / XMPTest.php
1 <?php
2
3 /**
4 * @todo covers tags
5 */
6 class XMPTest extends MediaWikiTestCase {
7
8 protected function setUp() {
9 parent::setUp();
10 if ( !extension_loaded( 'xml' ) ) {
11 $this->markTestSkipped( 'Requires libxml to do XMP parsing' );
12 }
13 }
14
15 /**
16 * Put XMP in, compare what comes out...
17 *
18 * @param $xmp String the actual xml data.
19 * @param $expected Array expected result of parsing the xmp.
20 * @param $info String Short sentence on what's being tested.
21 *
22 * @throws Exception
23 * @dataProvider provideXMPParse
24 *
25 * @covers XMPReader::parse
26 */
27 public function testXMPParse( $xmp, $expected, $info ) {
28 if ( !is_string( $xmp ) || !is_array( $expected ) ) {
29 throw new Exception( "Invalid data provided to " . __METHOD__ );
30 }
31 $reader = new XMPReader;
32 $reader->parse( $xmp );
33 $this->assertEquals( $expected, $reader->getResults(), $info, 0.0000000001 );
34 }
35
36 public static function provideXMPParse() {
37 $xmpPath = __DIR__ . '/../../data/xmp/';
38 $data = array();
39
40 // $xmpFiles format: array of arrays with first arg file base name,
41 // with the actual file having .xmp on the end for the xmp
42 // and .result.php on the end for a php file containing the result
43 // array. Second argument is some info on what's being tested.
44 $xmpFiles = array(
45 array( '1', 'parseType=Resource test' ),
46 array( '2', 'Structure with mixed attribute and element props' ),
47 array( '3', 'Extra qualifiers (that should be ignored)' ),
48 array( '3-invalid', 'Test ignoring qualifiers that look like normal props' ),
49 array( '4', 'Flash as qualifier' ),
50 array( '5', 'Flash as qualifier 2' ),
51 array( '6', 'Multiple rdf:Description' ),
52 array( '7', 'Generic test of several property types' ),
53 array( 'flash', 'Test of Flash property' ),
54 array( 'invalid-child-not-struct', 'Test child props not in struct or ignored' ),
55 array( 'no-recognized-props', 'Test namespace and no recognized props' ),
56 array( 'no-namespace', 'Test non-namespaced attributes are ignored' ),
57 array( 'bag-for-seq', "Allow bag's instead of seq's. (bug 27105)" ),
58 array( 'utf16BE', 'UTF-16BE encoding' ),
59 array( 'utf16LE', 'UTF-16LE encoding' ),
60 array( 'utf32BE', 'UTF-32BE encoding' ),
61 array( 'utf32LE', 'UTF-32LE encoding' ),
62 array( 'xmpExt', 'Extended XMP missing second part' ),
63 array( 'gps', 'Handling of exif GPS parameters in XMP' ),
64 );
65
66 foreach ( $xmpFiles as $file ) {
67 $xmp = file_get_contents( $xmpPath . $file[0] . '.xmp' );
68 // I'm not sure if this is the best way to handle getting the
69 // result array, but it seems kind of big to put directly in the test
70 // file.
71 $result = null;
72 include $xmpPath . $file[0] . '.result.php';
73 $data[] = array( $xmp, $result, '[' . $file[0] . '.xmp] ' . $file[1] );
74 }
75
76 return $data;
77 }
78
79 /** Test ExtendedXMP block support. (Used when the XMP has to be split
80 * over multiple jpeg segments, due to 64k size limit on jpeg segments.
81 *
82 * @todo This is based on what the standard says. Need to find a real
83 * world example file to double check the support for this is right.
84 *
85 * @covers XMPReader::parseExtended
86 */
87 public function testExtendedXMP() {
88 $xmpPath = __DIR__ . '/../../data/xmp/';
89 $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' );
90 $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' );
91
92 $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp
93 $length = pack( 'N', strlen( $extendedXMP ) );
94 $offset = pack( 'N', 0 );
95 $extendedPacket = $md5sum . $length . $offset . $extendedXMP;
96
97 $reader = new XMPReader();
98 $reader->parse( $standardXMP );
99 $reader->parseExtended( $extendedPacket );
100 $actual = $reader->getResults();
101
102 $expected = array(
103 'xmp-exif' => array(
104 'DigitalZoomRatio' => '0/10',
105 'Flash' => 9,
106 'FNumber' => '2/10',
107 )
108 );
109
110 $this->assertEquals( $expected, $actual );
111 }
112
113 /**
114 * This test has an extended XMP block with a wrong guid (md5sum)
115 * and thus should only return the StandardXMP, not the ExtendedXMP.
116 *
117 * @covers XMPReader::parseExtended
118 */
119 public function testExtendedXMPWithWrongGUID() {
120 $xmpPath = __DIR__ . '/../../data/xmp/';
121 $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' );
122 $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' );
123
124 $md5sum = '28C74E0AC2D796886759006FBE2E57B9'; // Note last digit.
125 $length = pack( 'N', strlen( $extendedXMP ) );
126 $offset = pack( 'N', 0 );
127 $extendedPacket = $md5sum . $length . $offset . $extendedXMP;
128
129 $reader = new XMPReader();
130 $reader->parse( $standardXMP );
131 $reader->parseExtended( $extendedPacket );
132 $actual = $reader->getResults();
133
134 $expected = array(
135 'xmp-exif' => array(
136 'DigitalZoomRatio' => '0/10',
137 'Flash' => 9,
138 )
139 );
140
141 $this->assertEquals( $expected, $actual );
142 }
143
144 /**
145 * Have a high offset to simulate a missing packet,
146 * which should cause it to ignore the ExtendedXMP packet.
147 *
148 * @covers XMPReader::parseExtended
149 */
150 public function testExtendedXMPMissingPacket() {
151 $xmpPath = __DIR__ . '/../../data/xmp/';
152 $standardXMP = file_get_contents( $xmpPath . 'xmpExt.xmp' );
153 $extendedXMP = file_get_contents( $xmpPath . 'xmpExt2.xmp' );
154
155 $md5sum = '28C74E0AC2D796886759006FBE2E57B7'; // of xmpExt2.xmp
156 $length = pack( 'N', strlen( $extendedXMP ) );
157 $offset = pack( 'N', 2048 );
158 $extendedPacket = $md5sum . $length . $offset . $extendedXMP;
159
160 $reader = new XMPReader();
161 $reader->parse( $standardXMP );
162 $reader->parseExtended( $extendedPacket );
163 $actual = $reader->getResults();
164
165 $expected = array(
166 'xmp-exif' => array(
167 'DigitalZoomRatio' => '0/10',
168 'Flash' => 9,
169 )
170 );
171
172 $this->assertEquals( $expected, $actual );
173 }
174 }