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