-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
Copy pathindex.js
311 lines (258 loc) · 8.22 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
const path = require(`path`)
const fs = require(`fs-extra`)
jest.mock(`async/queue`, () => () => {
return {
push: jest.fn(),
}
})
fs.ensureDirSync = jest.fn()
const {
base64,
fluid,
fixed,
queueImageResizing,
getImageSize,
} = require(`../`)
describe(`gatsby-plugin-sharp`, () => {
const args = {
duotone: false,
grayscale: false,
rotate: false,
}
const absolutePath = path.join(__dirname, `images/test.png`)
const file = getFileObject(absolutePath)
// used to find all breakpoints in a srcSet string
const findAllBreakpoints = srcSet => {
// RegEx to find all occurrences of 'Xw', where 'X' can be any int
const regEx = /[0-9]+w/g
return srcSet.match(regEx)
}
describe(`queueImageResizing`, () => {
it(`should round height when auto-calculated`, () => {
// Resize 144-density.png (281x136) with a 3px width
const result = queueImageResizing({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args: { width: 3 },
})
// Width should be: w = (3 * 136) / 281 = 1.451957295
// We expect value to be rounded to 1
expect(result.height).toBe(1)
})
})
describe(`fluid`, () => {
it(`includes responsive image properties, e.g. sizes, srcset, etc.`, async () => {
const result = await fluid({ file })
expect(result).toMatchSnapshot()
})
it(`adds pathPrefix if defined`, async () => {
const pathPrefix = `/blog`
const result = await fluid({
file,
args: {
pathPrefix,
},
})
expect(result.src.indexOf(pathPrefix)).toBe(0)
expect(result.srcSet.indexOf(pathPrefix)).toBe(0)
})
it(`keeps original file name`, async () => {
const result = await fluid({
file,
})
expect(path.parse(result.src).name).toBe(file.name)
expect(path.parse(result.srcSet).name).toBe(file.name)
})
it(`accounts for pixel density`, async () => {
const result = await fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args: {
sizeByPixelDensity: true,
},
})
expect(result).toMatchSnapshot()
})
it(`can optionally ignore pixel density`, async () => {
const result = await fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args: {
sizeByPixelDensity: false,
},
})
expect(result).toMatchSnapshot()
})
it(`does not change the arguments object it is given`, async () => {
const args = { maxWidth: 400 }
await fluid({
file,
args,
})
expect(args).toEqual({ maxWidth: 400 })
})
it(`infers the maxWidth if only maxHeight is given`, async () => {
const args = { maxHeight: 20 }
const result = await fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args,
})
expect(result.presentationWidth).toEqual(41)
})
it(`should throw if maxWidth is less than 1`, async () => {
const args = { maxWidth: 0 }
const result = fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args,
})
await expect(result).rejects.toThrow()
})
it(`accepts srcSet breakpoints`, async () => {
const srcSetBreakpoints = [50, 70, 150, 250]
const args = { srcSetBreakpoints }
const result = await fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args,
})
// width of the image tested
const originalWidth = 281
const expected = srcSetBreakpoints.map(size => `${size}w`)
// add the original size of `144-density.png`
expected.push(`${originalWidth}w`)
const actual = findAllBreakpoints(result.srcSet)
// should contain all requested sizes as well as the original size
expect(actual).toEqual(expect.arrayContaining(expected))
})
it(`should throw on srcSet breakpoints less than 1`, async () => {
const srcSetBreakpoints = [50, 0]
const args = { srcSetBreakpoints }
const result = fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args,
})
await expect(result).rejects.toThrow()
})
it(`ensure maxWidth is in srcSet breakpoints`, async () => {
const srcSetBreakpoints = [50, 70, 150]
const maxWidth = 200
const args = {
maxWidth,
srcSetBreakpoints,
}
const result = await fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args,
})
expect(result.srcSet).toEqual(expect.stringContaining(`${maxWidth}w`))
})
it(`reject any breakpoints larger than the original width`, async () => {
const srcSetBreakpoints = [
50,
70,
150,
250,
300, // this shouldn't be in the output as it's wider than the original
]
const maxWidth = 500 // this also shouldn't be in the output
const args = {
maxWidth,
srcSetBreakpoints,
}
const result = await fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args,
})
// width of the image tested
const originalWidth = 281
const expected = srcSetBreakpoints
// filter out the widths that are larger than the source image width
.filter(size => size < originalWidth)
.map(size => `${size}w`)
// add the original size of `144-density.png`
expected.push(`${originalWidth}w`)
const actual = findAllBreakpoints(result.srcSet)
// should contain all requested sizes as well as the original size
expect(actual).toEqual(expect.arrayContaining(expected))
// should contain no other sizes
expect(actual.length).toEqual(expected.length)
})
it(`prevents duplicate breakpoints`, async () => {
const srcSetBreakpoints = [50, 50, 100, 100, 100, 250, 250]
const maxWidth = 100
const args = {
maxWidth,
srcSetBreakpoints,
}
const result = await fluid({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args,
})
const originalWidth = 281
const expected = [`50w`, `100w`, `250w`, `${originalWidth}w`]
const actual = findAllBreakpoints(result.srcSet)
expect(actual).toEqual(expect.arrayContaining(expected))
expect(actual.length).toEqual(expected.length)
})
})
describe(`fixed`, () => {
console.warn = jest.fn()
beforeEach(() => {
console.warn.mockClear()
})
afterAll(() => {
console.warn.mockClear()
})
it(`does not warn when the requested width is equal to the image width`, async () => {
const args = { width: 1 }
const result = await fixed({
file,
args,
})
expect(result.width).toEqual(1)
expect(console.warn).toHaveBeenCalledTimes(0)
})
it(`warns when the requested width is greater than the image width`, async () => {
const args = { width: 2 }
const result = await fixed({
file,
args,
})
expect(result.width).toEqual(1)
expect(console.warn).toHaveBeenCalledTimes(1)
})
it(`correctly infers the width when only the height is given`, async () => {
const args = { height: 10 }
const result = await fixed({
file: getFileObject(path.join(__dirname, `images/144-density.png`)),
args,
})
expect(result.width).toEqual(21)
})
})
describe(`base64`, () => {
it(`converts image to base64`, async () => {
const result = await base64({
file,
args,
})
expect(result).toMatchSnapshot()
})
})
describe(`image quirks`, () => {
// issue https://github.com/nodeca/probe-image-size/issues/20
it(`handles padding bytes correctly`, () => {
const result = getImageSize(
getFileObject(path.join(__dirname, `images/padding-bytes.jpg`))
)
expect(result).toMatchSnapshot()
})
})
})
function getFileObject(absolutePath) {
return {
id: `${absolutePath} absPath of file`,
name: `test`,
absolutePath,
extension: `png`,
internal: {
contentDigest: `1234`,
},
}
}