Skip to content

Commit 1b5b5cf

Browse files
[core] Bugfix/media capabilities use effect (#55)
* doc: improved code styling in readme * infra: uninstalled react-dom * chore: cleaned up * infra: extracted supported from hook in useMediaCapabilities * doc: cleaned code snippet for useMediaCapabilities in README * [fix] added use effect dependencies in useMediaCapabilitiesDecodingInfo * fix: removed unnecessary code * [fix] fixed media capabilities unit test in the basic level * [fix] push supported into hook for easy unit test * [fix] uninstalled @babel/plugin-transform-runtime
1 parent 40b093a commit 1b5b5cf

File tree

5 files changed

+212
-173
lines changed

5 files changed

+212
-173
lines changed

babel.config.js

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
/*
2-
* Copyright 2019 Google LLC
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the 'License');
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* https://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an 'AS IS' BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
17-
module.exports = {
18-
presets: [
19-
"@babel/preset-env"
20-
]
21-
};
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the 'License');
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an 'AS IS' BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
module.exports = {
18+
presets: [
19+
"@babel/preset-env"
20+
]
21+
};

media-capabilities/index.js

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,35 @@
1-
/*
2-
* Copyright 2019 Google LLC
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* https://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
import { useState, useEffect } from 'react';
17-
18-
const supported = typeof window !== 'undefined' && 'mediaCapabilities' in navigator;
19-
20-
const useMediaCapabilitiesDecodingInfo = (mediaDecodingConfig, initialMediaCapabilitiesInfo = {}) => {
21-
initialMediaCapabilitiesInfo = {
22-
...initialMediaCapabilitiesInfo
23-
};
24-
25-
const [mediaCapabilitiesInfo, setMediaCapabilitiesInfo] = useState(initialMediaCapabilitiesInfo);
26-
27-
useEffect(() => {
28-
supported &&
29-
navigator
30-
.mediaCapabilities
31-
.decodingInfo(mediaDecodingConfig)
32-
.then(setMediaCapabilitiesInfo)
33-
.catch(error => console.error(error));
34-
}, []);
35-
36-
return { supported, mediaCapabilitiesInfo };
37-
};
38-
39-
export { useMediaCapabilitiesDecodingInfo };
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { useState, useEffect } from 'react';
18+
19+
const useMediaCapabilitiesDecodingInfo = (mediaDecodingConfig, initialMediaCapabilitiesInfo = {}) => {
20+
const supported = typeof navigator !== 'undefined' && 'mediaCapabilities' in navigator;
21+
const [mediaCapabilitiesInfo, setMediaCapabilitiesInfo] = useState(initialMediaCapabilitiesInfo);
22+
23+
useEffect(() => {
24+
supported &&
25+
navigator
26+
.mediaCapabilities
27+
.decodingInfo(mediaDecodingConfig)
28+
.then(setMediaCapabilitiesInfo)
29+
.catch(error => console.error(error));
30+
}, [mediaDecodingConfig]);
31+
32+
return { supported, mediaCapabilitiesInfo };
33+
};
34+
35+
export { useMediaCapabilitiesDecodingInfo };
Lines changed: 117 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,117 @@
1-
/*
2-
* Copyright 2019 Google LLC
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the 'License');
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* https://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an 'AS IS' BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
17-
import { renderHook } from '@testing-library/react-hooks';
18-
19-
const mediaDecodingConfig = {
20-
type: 'file',
21-
audio: {
22-
contentType: 'audio/mp3',
23-
channels: 2,
24-
bitrate: 132700,
25-
samplerate: 5200
26-
}
27-
};
28-
29-
const mediaCapabilitiesMapper = {
30-
'audio/mp3': {
31-
powerEfficient: true,
32-
smooth: true,
33-
supported: true
34-
}
35-
};
36-
37-
describe('useMediaCapabilitiesDecodingInfo', () => {
38-
test('should return supported flag on unsupported platforms', () => {
39-
jest.isolateModules(() => {
40-
const { useMediaCapabilitiesDecodingInfo } = require('.');
41-
const { result } = renderHook(() => useMediaCapabilitiesDecodingInfo(mediaDecodingConfig));
42-
43-
expect(result.current.supported).toEqual(false);
44-
})
45-
});
46-
47-
test('should return supported flag on unsupported platforms and no config given', () => {
48-
jest.isolateModules(() => {
49-
const { useMediaCapabilitiesDecodingInfo } = require('.');
50-
const { result } = renderHook(() => useMediaCapabilitiesDecodingInfo());
51-
52-
expect(result.current.supported).toEqual(false);
53-
})
54-
});
55-
56-
test('should return initialMediaCapabilitiesInfo for unsupported', () => {
57-
jest.isolateModules(() => {
58-
const initialMediaCapabilitiesInfo = {
59-
supported: true,
60-
smooth: false,
61-
powerEfficient: true
62-
};
63-
64-
const { useMediaCapabilitiesDecodingInfo } = require('.');
65-
const { result } = renderHook(() => useMediaCapabilitiesDecodingInfo(mediaDecodingConfig, initialMediaCapabilitiesInfo));
66-
67-
expect(result.current.mediaCapabilitiesInfo.supported).toBe(true);
68-
expect(result.current.mediaCapabilitiesInfo.smooth).toEqual(false);
69-
expect(result.current.mediaCapabilitiesInfo.powerEfficient).toEqual(true);
70-
});
71-
});
72-
73-
test('should return supported flag when no config given', (done) => {
74-
jest.isolateModules(() => {
75-
global.navigator.mediaCapabilities = {
76-
decodingInfo: () => new Promise(resolve => resolve(true))
77-
};
78-
79-
const { useMediaCapabilitiesDecodingInfo } = require('.');
80-
const { result, waitForNextUpdate } = renderHook(() => useMediaCapabilitiesDecodingInfo());
81-
82-
waitForNextUpdate()
83-
.then(() => {
84-
expect(result.current.supported).toEqual(true);
85-
86-
done();
87-
})
88-
.catch(err => done(err));
89-
});
90-
});
91-
92-
test('should return mediaCapabilitiesInfo for given media configuration', (done) => {
93-
jest.isolateModules(() => {
94-
global.navigator.mediaCapabilities = {
95-
decodingInfo: () => new Promise(resolve => resolve(mediaCapabilitiesMapper[mediaDecodingConfig.audio.contentType]))
96-
};
97-
98-
const { useMediaCapabilitiesDecodingInfo } = require('.');
99-
const { result, waitForNextUpdate } = renderHook(() => useMediaCapabilitiesDecodingInfo(mediaDecodingConfig));
100-
101-
waitForNextUpdate()
102-
.then(() => {
103-
expect(result.current.mediaCapabilitiesInfo.powerEfficient).toEqual(true);
104-
expect(result.current.mediaCapabilitiesInfo.smooth).toEqual(true);
105-
expect(result.current.mediaCapabilitiesInfo.supported).toEqual(true);
106-
107-
done();
108-
})
109-
.catch(err => done(err));
110-
});
111-
});
112-
});
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the 'License');
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an 'AS IS' BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import 'babel-polyfill';
18+
import { renderHook } from '@testing-library/react-hooks';
19+
20+
const mediaDecodingConfig = {
21+
type: 'file',
22+
audio: {
23+
contentType: 'audio/mp3',
24+
channels: 2,
25+
bitrate: 132700,
26+
samplerate: 5200
27+
}
28+
};
29+
30+
const mediaCapabilitiesMapper = {
31+
'audio/mp3': {
32+
powerEfficient: true,
33+
smooth: true,
34+
supported: true
35+
}
36+
};
37+
38+
describe('useMediaCapabilitiesDecodingInfo', () => {
39+
test('should return supported flag on unsupported platforms', () => {
40+
const { useMediaCapabilitiesDecodingInfo } = require('./');
41+
const { result } = renderHook(() => useMediaCapabilitiesDecodingInfo(mediaDecodingConfig));
42+
43+
expect(result.current.supported).toEqual(false);
44+
});
45+
46+
test('should return supported flag on unsupported platforms and no config given', () => {
47+
const { useMediaCapabilitiesDecodingInfo } = require('./');
48+
const { result } = renderHook(() => useMediaCapabilitiesDecodingInfo());
49+
50+
expect(result.current.supported).toEqual(false);
51+
});
52+
53+
test('should return initialMediaCapabilitiesInfo for unsupported', () => {
54+
const initialMediaCapabilitiesInfo = {
55+
supported: true,
56+
smooth: false,
57+
powerEfficient: true
58+
};
59+
60+
const { useMediaCapabilitiesDecodingInfo } = require('./');
61+
const { result } = renderHook(() => useMediaCapabilitiesDecodingInfo(mediaDecodingConfig, initialMediaCapabilitiesInfo));
62+
63+
expect(result.current.mediaCapabilitiesInfo.supported).toBe(true);
64+
expect(result.current.mediaCapabilitiesInfo.smooth).toEqual(false);
65+
expect(result.current.mediaCapabilitiesInfo.powerEfficient).toEqual(true);
66+
});
67+
68+
test('should return supported flag when no config given', async () => {
69+
const originalError = console.error;
70+
console.error = jest.fn();
71+
72+
const mockDecodingInfo = jest.fn().mockImplementation(() => Promise.resolve({
73+
supported: true
74+
}));
75+
76+
global.navigator.mediaCapabilities = {
77+
decodingInfo: mockDecodingInfo
78+
};
79+
80+
const { useMediaCapabilitiesDecodingInfo } = require('./');
81+
82+
try {
83+
const { result, waitForNextUpdate } = renderHook(() => useMediaCapabilitiesDecodingInfo());
84+
await waitForNextUpdate();
85+
86+
expect(result.current.supported).toEqual(true);
87+
} finally {
88+
console.error = originalError;
89+
}
90+
});
91+
92+
test('should return mediaCapabilitiesInfo for given media configuration', async () => {
93+
const originalError = console.error;
94+
console.error = jest.fn();
95+
96+
const mockDecodingInfo = jest.fn().mockImplementation(() => Promise.resolve({
97+
...mediaCapabilitiesMapper[mediaDecodingConfig.audio.contentType]
98+
}));
99+
100+
global.navigator.mediaCapabilities = {
101+
decodingInfo: mockDecodingInfo
102+
};
103+
104+
const { useMediaCapabilitiesDecodingInfo } = require('./');
105+
106+
try {
107+
const { result, waitForNextUpdate } = renderHook(() => useMediaCapabilitiesDecodingInfo(mediaDecodingConfig));
108+
await waitForNextUpdate();
109+
110+
expect(result.current.mediaCapabilitiesInfo.powerEfficient).toEqual(true);
111+
expect(result.current.mediaCapabilitiesInfo.smooth).toEqual(true);
112+
expect(result.current.mediaCapabilitiesInfo.supported).toEqual(true);
113+
} finally {
114+
console.error = originalError;
115+
}
116+
});
117+
});

0 commit comments

Comments
 (0)