react-native/Libraries/Image/__tests__/resolveAssetSource-test.js
Alex Kotliarskyi 10b599c343 Load assets from same folder as JS bundle
Summary: Fixes #3679, see https://github.com/facebook/react-native/issues/3679

The idea is to always load images from the same folder that we loaded JS bundle.

This doesn't change the current behavior, since `imageNamed:` inferred the
absolute path to the image from app's bundle, but now we make it explicit.

The benefit for OTA updates implementations is that they can simply ask RN
to load js from some `~/Documents/<build-id>/main.jsbundle` folder and RN will
look for images in `~/Documents/<build-id>/assets/`.

Note that for Android we will have to come out with a different plan, since
in prod we load images from built-in resources.

public

Reviewed By: vjeux

Differential Revision: D2616995

fb-gh-sync-id: 2906c62380280ecb987525edf9a0e3e727a1008b
2015-11-05 12:53:26 -08:00

175 lines
4.8 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
jest
.dontMock('AssetRegistry')
.dontMock('../resolveAssetSource');
var AssetRegistry = require('AssetRegistry');
var Platform = require('Platform');
var NativeModules = require('NativeModules');
var resolveAssetSource = require('../resolveAssetSource');
function expectResolvesAsset(input, expectedSource) {
var assetId = AssetRegistry.registerAsset(input);
expect(resolveAssetSource(assetId)).toEqual(expectedSource);
}
describe('resolveAssetSource', () => {
beforeEach(() => {
jest.resetModuleRegistry();
});
it('returns same source for simple static and network images', () => {
var source1 = {uri: 'https://www.facebook.com/logo'};
expect(resolveAssetSource(source1)).toBe(source1);
var source2 = {uri: 'logo'};
expect(resolveAssetSource(source2)).toBe(source2);
});
it('does not change deprecated assets', () => {
expect(resolveAssetSource({
deprecated: true,
width: 100,
height: 200,
uri: 'logo',
})).toEqual({
deprecated: true,
width: 100,
height: 200,
uri: 'logo',
});
});
it('ignores any weird data', () => {
expect(resolveAssetSource(null)).toBe(null);
expect(resolveAssetSource(42)).toBe(null);
expect(resolveAssetSource('nonsense')).toBe(null);
});
describe('bundle was loaded from network (DEV)', () => {
beforeEach(() => {
NativeModules.SourceCode.scriptURL =
'http://10.0.0.1:8081/main.bundle';
Platform.OS = 'ios';
});
it('uses network image', () => {
expectResolvesAsset({
__packager_asset: true,
fileSystemLocation: '/root/app/module/a',
httpServerLocation: '/assets/module/a',
width: 100,
height: 200,
scales: [1],
hash: '5b6f00f',
name: 'logo',
type: 'png',
}, {
__packager_asset: true,
width: 100,
height: 200,
uri: 'http://10.0.0.1:8081/assets/module/a/logo.png?platform=ios&hash=5b6f00f',
scale: 1,
});
});
it('picks matching scale', () => {
expectResolvesAsset({
__packager_asset: true,
fileSystemLocation: '/root/app/module/a',
httpServerLocation: '/assets/module/a',
width: 100,
height: 200,
scales: [1, 2, 3],
hash: '5b6f00f',
name: 'logo',
type: 'png',
}, {
__packager_asset: true,
width: 100,
height: 200,
uri: 'http://10.0.0.1:8081/assets/module/a/logo@2x.png?platform=ios&hash=5b6f00f',
scale: 2,
});
});
});
describe('bundle was loaded from file on iOS', () => {
beforeEach(() => {
NativeModules.SourceCode.scriptURL =
'file:///Path/To/Sample.app/main.bundle';
Platform.OS = 'ios';
});
it('uses pre-packed image', () => {
expectResolvesAsset({
__packager_asset: true,
fileSystemLocation: '/root/app/module/a',
httpServerLocation: '/assets/module/a',
width: 100,
height: 200,
scales: [1],
hash: '5b6f00f',
name: 'logo',
type: 'png',
}, {
__packager_asset: true,
width: 100,
height: 200,
uri: '/Path/To/Sample.app/assets/module/a/logo.png',
scale: 1,
});
});
});
describe('bundle was loaded from file on Android', () => {
beforeEach(() => {
NativeModules.SourceCode.scriptURL =
'file:///Path/To/Simulator/main.bundle';
Platform.OS = 'android';
});
it('uses pre-packed image', () => {
expectResolvesAsset({
__packager_asset: true,
fileSystemLocation: '/root/app/module/a',
httpServerLocation: '/assets/AwesomeModule/Subdir',
width: 100,
height: 200,
scales: [1],
hash: '5b6f00f',
name: '!@Logo#1_€', // Invalid chars shouldn't get passed to native
type: 'png',
}, {
__packager_asset: true,
width: 100,
height: 200,
uri: 'awesomemodule_subdir_logo1_',
scale: 1,
});
});
});
});
describe('resolveAssetSource.pickScale', () => {
it('picks matching scale', () => {
expect(resolveAssetSource.pickScale([1], 2)).toBe(1);
expect(resolveAssetSource.pickScale([1, 2, 3], 2)).toBe(2);
expect(resolveAssetSource.pickScale([1, 2], 3)).toBe(2);
expect(resolveAssetSource.pickScale([1, 2, 3, 4], 3.5)).toBe(4);
expect(resolveAssetSource.pickScale([3, 4], 2)).toBe(3);
expect(resolveAssetSource.pickScale([], 2)).toBe(1);
});
});