UNPKG

6.9 kBJavaScriptView Raw
1
2var should = require('chai').should();
3var expect = require('chai').expect;
4var fs = require('fs');
5var exec = require('child_process').exec;
6var piexif = require('piexifjs');
7var jpegjs = require('jpeg-js');
8var jo = require('../src/main.js');
9
10describe('jpeg-autorotate', function()
11{
12
13 itShouldTransform(__dirname + '/samples/image_2.jpg', 'image_2.jpg');
14 itShouldTransform(__dirname + '/samples/image_3.jpg', 'image_3.jpg');
15 itShouldTransform(__dirname + '/samples/image_4.jpg', 'image_4.jpg');
16 itShouldTransform(__dirname + '/samples/image_5.jpg', 'image_5.jpg');
17 itShouldTransform(__dirname + '/samples/image_6.jpg', 'image_6.jpg');
18 itShouldTransform(__dirname + '/samples/image_7.jpg', 'image_7.jpg');
19 itShouldTransform(__dirname + '/samples/image_8.jpg', 'image_8.jpg');
20 itShouldTransform(__dirname + '/samples/image_exif.jpg', 'image_exif.jpg');
21 itShouldTransform(fs.readFileSync(__dirname + '/samples/image_8.jpg'), 'From a buffer');
22
23 it('Should return an error if the orientation is 1', function(done)
24 {
25 jo.rotate(__dirname + '/samples/image_1.jpg', {}, function(error, buffer, orientation)
26 {
27 error.should.have.property('code').equal(jo.errors.correct_orientation);
28 Buffer.isBuffer(buffer).should.be.ok;
29 done();
30 });
31 });
32
33 it('Should return an error if the image does not exist', function(done)
34 {
35 jo.rotate('foo.jpg', {}, function(error, buffer, orientation)
36 {
37 error.should.have.property('code').equal(jo.errors.read_file);
38 expect(buffer).to.equal(null);
39 expect(orientation).to.equal(null);
40 done();
41 });
42 });
43
44 it('Should return an error if the file is not an image', function(done)
45 {
46 jo.rotate(__dirname + '/samples/textfile.md', {}, function(error, buffer, orientation)
47 {
48 error.should.have.property('code').equal(jo.errors.read_exif);
49 expect(buffer).to.equal(null);
50 expect(orientation).to.equal(null);
51 done();
52 });
53 });
54
55 it('Should return an error if the path is not a string/buffer', function(done)
56 {
57 jo.rotate(['foo'], {}, function(error, buffer, orientation)
58 {
59 error.should.have.property('code').equal(jo.errors.read_file);
60 expect(buffer).to.equal(null);
61 expect(orientation).to.equal(null);
62 done();
63 });
64 });
65
66 it('Should work if `options` is not an object', function(done)
67 {
68 jo.rotate(__dirname + '/samples/image_2.jpg', 'options', function(error, buffer, orientation)
69 {
70 expect(error).to.equal(null);
71 Buffer.isBuffer(buffer).should.be.ok;
72 expect(orientation).to.equal(2);
73 done();
74 });
75 });
76
77 it('Should return an error if the image has no orientation tag', function(done)
78 {
79 jo.rotate(__dirname + '/samples/image_no_orientation.jpg', {}, function(error, buffer, orientation)
80 {
81 error.should.have.property('code').equal(jo.errors.no_orientation);
82 Buffer.isBuffer(buffer).should.be.ok;
83 expect(orientation).to.equal(null);
84 done();
85 });
86 });
87
88 it('Should return an error if the image has an unknown orientation tag', function(done)
89 {
90 jo.rotate(__dirname + '/samples/image_unknown_orientation.jpg', {}, function(error, buffer, orientation)
91 {
92 error.should.have.property('code').equal(jo.errors.unknown_orientation);
93 Buffer.isBuffer(buffer).should.be.ok;
94 expect(orientation).to.equal(null);
95 done();
96 });
97 });
98
99 it('Should run on CLI', function(done)
100 {
101 var cli = __dirname + '/../src/cli.js';
102 var ref = __dirname + '/samples/image_2.jpg';
103 var tmp = __dirname + '/samples/image_2_cli.jpg';
104 var command = 'cp ' + ref + ' ' + tmp + ' && ' + cli + ' ' + tmp + ' && rm ' + tmp;
105 exec(command, function(error, stdout, stderr)
106 {
107 stdout.should.be.a('string').and.contain('Processed (Orientation was 2)');
108 done();
109 });
110 });
111
112 // @todo test jo.errors.read_exif (corrupted EXIF data ?)
113 // @todo test jo.errors.rotate_file (corrupted JPEG ?)
114
115});
116
117/**
118 * Tries to transform the given path/buffer, and checks data integrity (EXIF, dimensions)
119 * @param path_or_buffer
120 * @param label
121 */
122function itShouldTransform(path_or_buffer, label)
123{
124 it('Should rotate image (' + label + ')', function(done)
125 {
126 this.timeout(10000);
127 var orig_buffer = typeof path_or_buffer === 'string' ? fs.readFileSync(path_or_buffer) : path_or_buffer;
128 var orig_exif = piexif.load(orig_buffer.toString('binary'));
129 var orig_jpeg = jpegjs.decode(orig_buffer);
130 jo.rotate(path_or_buffer, {}, function(error, buffer, orientation)
131 {
132 if (error)
133 {
134 throw error;
135 }
136 var dest_exif = piexif.load(buffer.toString('binary'));
137 var dest_jpeg = jpegjs.decode(buffer);
138 if (orientation < 5 && (orig_jpeg.width !== dest_jpeg.width || orig_jpeg.height !== dest_jpeg.height))
139 {
140 throw new Eror('Dimensions do not match');
141 }
142 if (orientation >= 5 && (orig_jpeg.width !== dest_jpeg.height || orig_jpeg.height !== dest_jpeg.width))
143 {
144 throw new Eror('Dimensions do not match');
145 }
146 if (!compareEXIF(orig_exif, dest_exif))
147 {
148 throw new Error('EXIF do not match');
149 }
150 done();
151 });
152 });
153}
154
155/**
156 * Compares EXIF arrays
157 * The properties allowed to differ between the two versions are set to 0
158 * @param orig
159 * @param dest
160 */
161function compareEXIF(orig, dest)
162{
163 orig['thumbnail'] = 0; // The thumbnail
164 dest['thumbnail'] = 0;
165 orig['0th'][piexif.ImageIFD.Orientation] = 0; // Orientation
166 dest['0th'][piexif.ImageIFD.Orientation] = 0;
167 orig['0th'][piexif.ImageIFD.ExifTag] = 0; // Pointer to the Exif IFD
168 dest['0th'][piexif.ImageIFD.ExifTag] = 0;
169 orig['Exif'][piexif.ExifIFD.PixelXDimension] = 0; // Image width
170 dest['Exif'][piexif.ExifIFD.PixelXDimension] = 0;
171 orig['Exif'][piexif.ExifIFD.PixelYDimension] = 0; // Image height
172 dest['Exif'][piexif.ExifIFD.PixelYDimension] = 0;
173 orig['1st'][piexif.ImageIFD.JPEGInterchangeFormat] = 0; // Offset to the start byte of the thumbnail
174 dest['1st'][piexif.ImageIFD.JPEGInterchangeFormat] = 0;
175 orig['1st'][piexif.ImageIFD.JPEGInterchangeFormatLength] = 0; // Number of bytes of the thumbnail
176 dest['1st'][piexif.ImageIFD.JPEGInterchangeFormatLength] = 0;
177
178 var orig_json = JSON.stringify(orig);
179 var dest_json = JSON.stringify(dest);
180
181 return orig_json === dest_json;
182}