1import * as ImageManipulator from 'expo-image-manipulator';
2import * as FileSystem from 'expo-file-system';
3import { Asset } from 'expo-asset';
4
5export const name = 'ImageManipulator';
6
7export async function test(t) {
8  t.describe('ImageManipulator', async () => {
9    let image;
10
11    t.beforeAll(async () => {
12      image = Asset.fromModule(require('../assets/example_image_1.jpg'));
13      await image.downloadAsync();
14    });
15
16    t.describe('manipulateAsync()', async () => {
17      t.it('returns valid image', async () => {
18        const result = await ImageManipulator.manipulateAsync(image.localUri, [
19          { resize: { width: 100, height: 100 } },
20        ]);
21        t.expect(result).toBeDefined();
22        t.expect(typeof result.uri).toBe('string');
23        t.expect(typeof result.width).toBe('number');
24        t.expect(typeof result.height).toBe('number');
25      });
26
27      t.it('saves with default format', async () => {
28        const result = await ImageManipulator.manipulateAsync(image.localUri, [
29          { resize: { width: 100, height: 100 } },
30        ]);
31        t.expect(result.uri.endsWith('.jpg')).toBe(true);
32      });
33
34      t.it('saves as JPEG', async () => {
35        const result = await ImageManipulator.manipulateAsync(
36          image.localUri,
37          [{ resize: { width: 100, height: 100 } }],
38          {
39            format: ImageManipulator.SaveFormat.JPEG,
40          }
41        );
42
43        t.expect(result.uri.endsWith('.jpg')).toBe(true);
44      });
45
46      t.it('saves as PNG', async () => {
47        const result = await ImageManipulator.manipulateAsync(
48          image.localUri,
49          [{ resize: { width: 100, height: 100 } }],
50          {
51            format: ImageManipulator.SaveFormat.PNG,
52          }
53        );
54
55        t.expect(result.uri.endsWith('.png')).toBe(true);
56      });
57
58      t.it('provides Base64 with no newline terminator', async () => {
59        const result = await ImageManipulator.manipulateAsync(
60          image.localUri,
61          [{ resize: { width: 100, height: 100 } }],
62          {
63            base64: true,
64          }
65        );
66
67        t.expect(typeof result.base64).toBe('string');
68        t.expect(result.base64).not.toContain('\n');
69        t.expect(result.base64).not.toContain('\r');
70      });
71
72      t.it('performs compression', async () => {
73        const result = await ImageManipulator.manipulateAsync(
74          image.localUri,
75          [{ flip: ImageManipulator.FlipType.Vertical }],
76          {
77            compress: 0.0,
78          }
79        );
80
81        const imageInfo = await FileSystem.getInfoAsync(image.localUri);
82        const resultInfo = await FileSystem.getInfoAsync(result.uri);
83
84        t.expect(imageInfo.size).toBeGreaterThan(resultInfo.size);
85      });
86
87      t.it('rotates images', async () => {
88        const result = await ImageManipulator.manipulateAsync(image.localUri, [{ rotate: 45 }]);
89        t.expect(result.width).toBeGreaterThan(image.width);
90      });
91
92      t.it('flips horizontally', async () => {
93        const result = await ImageManipulator.manipulateAsync(image.localUri, [
94          { flip: ImageManipulator.FlipType.Horizontal },
95        ]);
96        t.expect(result.width).toBe(image.width);
97        t.expect(result.height).toBe(image.height);
98      });
99
100      t.it('flips vertically', async () => {
101        const result = await ImageManipulator.manipulateAsync(image.localUri, [
102          { flip: ImageManipulator.FlipType.Vertical },
103        ]);
104        t.expect(result.width).toBe(image.width);
105        t.expect(result.height).toBe(image.height);
106      });
107
108      t.it('resizes image', async () => {
109        const result = await ImageManipulator.manipulateAsync(image.localUri, [
110          { resize: { width: 100, height: 100 } },
111        ]);
112        t.expect(result.height).toBe(100);
113        t.expect(result.width).toBe(100);
114      });
115
116      t.it('cropes image', async () => {
117        const result = await ImageManipulator.manipulateAsync(image.localUri, [
118          { crop: { originX: 20, originY: 20, width: 100, height: 100 } },
119        ]);
120        t.expect(result.height).toBe(100);
121        t.expect(result.width).toBe(100);
122      });
123
124      t.it('performs multiple transformations', async () => {
125        const result = await ImageManipulator.manipulateAsync(image.localUri, [
126          { resize: { width: 200, height: 200 } },
127          { flip: ImageManipulator.FlipType.Vertical },
128          { rotate: 45 },
129          { crop: { originX: 20, originY: 20, width: 100, height: 100 } },
130        ]);
131        t.expect(result.height).toBe(100);
132        t.expect(result.width).toBe(100);
133      });
134    });
135  });
136}
137