Skip to content

Commit

Permalink
Added start of JS unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick committed Oct 23, 2017
1 parent a7c756d commit 3b7ea14
Show file tree
Hide file tree
Showing 3 changed files with 325 additions and 0 deletions.
66 changes: 66 additions & 0 deletions __tests__/__mocks__/react-native-mapbox-gl.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
jest.mock('NativeModules', () => {
function keyMirror (keys) {
let obj = {};
keys.forEach((key) => obj[key] = key);
return obj;
}

// Mock of what the native code puts on the JS object
const MapboxGLNativeMock = {
// constants
UserTrackingModes: keyMirror([
'None',
'Follow',
'FollowWithCourse',
'FollowWithHeading',
]),
StyleURL: keyMirror([
'Street',
'Dark',
'Light',
'Outdoors',
'Satellite',
'SatelliteStreet',
'TrafficDay',
'TrafficNight',
]),
EventTypes: keyMirror([
'MapClick',
'MapLongClick',
'RegionWillChange',
'RegionIsChanging',
'RegionDidChange',
'WillStartLoadingMap',
'DidFinishLoadingMap',
'DidFailLoadingMap',
'WillStartRenderingFrame',
'DidFinishRenderingFrame',
'DidFinishRenderingFrameFully',
'DidFinishLoadingStyle',
'SetCameraComplete',
]),
CameraModes: keyMirror([
'Flight',
'Ease',
'None',
]),
StyleSource: keyMirror([
'DefaultSourceID',
]),
InterpolationMode: keyMirror([
'Exponential',
'Categorical',
'Interval',
'Identity',
]),

// methods
setAccessToken: jest.fn(),
getAccessToken: () => Promise.resolve('test-token'),
requestPermissions: () => Promise.resolve(true),
};

return {
MGLModule: MapboxGLNativeMock,
};
});
40 changes: 40 additions & 0 deletions __tests__/interface.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import MapboxGL from '../javascript';

describe('Public Interface', () => {
it('should contain all expected components and utils', () => {
const actualKeys = Object.keys(MapboxGL);
const expectedKeys = [
// components
'MapView',
'StyleSheet',

// layers
'FillLayer',
'FillExtrusionLayer',
'CircleLayer',
'LineLayer',
'SymbolLayer',

// sources
'VectorSource',
'ShapeSource',

// constants
'UserTrackingModes',
'StyleURL',
'EventTypes',
'CameraModes',
'StyleSource',
'InterpolationMode',

// methods
'setAccessToken',
'getAccessToken',
'requestPermissions',

// utils
'geoUtils',
];
actualKeys.forEach((key) => expect(expectedKeys).toContain(key));
});
});
219 changes: 219 additions & 0 deletions __tests__/utils/MapboxStyleSheet.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
import MapboxGL from '../../javascript';

describe('MapboxStyleSheet', () => {
const BLUE_INT = 4278190335;
const GREEN_INT = 4278222848;

it('should create constant item', () => {
verifyStyleSheetsMatch({ fillOpacity: 0.84 }, {
__MAPBOX_STYLESHEET__: true,
fillOpacity: {
type: 'constant',
payload: { value: 0.84 },
},
});
});

it('should create image item', () => {
verifyStyleSheetsMatch({ fillPattern: 'test' }, {
__MAPBOX_STYLESHEET__: true,
fillPattern: {
type: 'constant',
payload: { value: 'test', image: true },
},
});
});

it('should create translate item', () => {
verifyStyleSheetsMatch({ fillTranslation: { x: 1, y: 2 } }, {
__MAPBOX_STYLESHEET__: true,
fillTranslation: {
type: 'translation',
payload: { value: [1, 2] },
},
});
});

it('should create camera function', () => {
const stops = { 1: 'blue', 2: 'green' };
const styleFunction = MapboxGL.StyleSheet.camera(stops, 'mode');

verifyStyleSheetsMatch({ fillColor: styleFunction }, {
fillColor: {
type: 'function',
payload: {
fn: 'camera',
stops: {
1: { type: 'color', payload: { value: BLUE_INT } },
2: { type: 'color', payload: { value: GREEN_INT } },
},
mode: 'mode',
},
},
__MAPBOX_STYLESHEET__: true,
});
});

it('should create composite function', () => {
const stops = {
1: [0, 'blue'],
16: [3, 'green'],
20: [5, 'blue'],
};
const styleFunction = MapboxGL.StyleSheet.composite(stops, 'rating', 'mode');

verifyStyleSheetsMatch({ fillColor: styleFunction }, {
fillColor: {
type: 'function',
payload: {
fn: 'composite',
mode: 'mode',
attributeName: 'rating',
stops: {
1: { type: 'color', payload: { value: BLUE_INT, propertyValue: 0 } },
16: { type: 'color', payload: { value: GREEN_INT, propertyValue: 3 } },
20: { type: 'color', payload: { value: BLUE_INT, propertyValue: 5 } },
},
}, // payload
}, // fillPattern
__MAPBOX_STYLESHEET__: true,
});

});

it('should create source function', () => {
const stops = { bergan: 'blue', hudson: 'green' };
const styleFunction = MapboxGL.StyleSheet.source(stops, 'county', 'mode');

verifyStyleSheetsMatch({ fillColor: styleFunction }, {
fillColor: {
type: 'function',
payload: {
fn: 'source',
mode: 'mode',
attributeName: 'county',
stops: {
bergan: { type: 'color', payload: { value: BLUE_INT } },
hudson: { type: 'color', payload: { value: GREEN_INT } },
},
}, // payload
}, // fillColor
__MAPBOX_STYLESHEET__: true,
});
});

it('should create stylesheet with multiple constant style fields', () => {
const styles = {
fillOpacity: 0.84,
fillPattern: 'test',
};

verifyStyleSheetsMatch(styles, {
__MAPBOX_STYLESHEET__: true,
fillOpacity: { type: 'constant', payload: { value: 0.84 } },
fillPattern: { type: 'constant', payload: { value: 'test', image: true } },
});
});

it('should create stylesheet with a mix of stlye functions and constants', () => {
const styles = {
fillColor: MapboxGL.StyleSheet.source({ bergan: 'blue' }, 'county', 'mode'),
fillOpacity: 0.84,
};

verifyStyleSheetsMatch(styles, {
__MAPBOX_STYLESHEET__: true,
fillColor: {
type: 'function',
payload: {
fn: 'source',
mode: 'mode',
attributeName: 'county',
stops: {
bergan: { type: 'color', payload: { value: BLUE_INT } },
},
},
},
fillOpacity: { type: 'constant', payload: { value: 0.84 } },
});

});

it('should create config nested one level deep', () => {
const styles = {
water: {
fillColor: 'green',
fillOpacity: 0.40,
},
building: {
fillColor: 'blue',
fillOpacity: 0.84,
},
};

verifyStyleSheetsMatch(styles, {
__MAPBOX_STYLESHEET__: true,
water: {
fillColor: { type: 'color', payload: { value: GREEN_INT } },
fillOpacity: { type: 'constant', payload: { value: 0.40 } },
},
building: {
fillColor: { type: 'color', payload: { value: BLUE_INT } },
fillOpacity: { type: 'constant', payload: { value: 0.84 } },
},
});
});

it('should not recreate a stylesheet if it is already a stylesheet', () => {
const styleSheet = MapboxGL.StyleSheet.create({ fillOpacity: 0.84 });
expect(styleSheet).toEqual(MapboxGL.StyleSheet.create(styleSheet));
});

it('should throw error for invalid property', () => {
expect(() => {
MapboxGL.StyleSheet.create({ fakeProperty: 0.84 });
}).toThrow();

expect(() => {
MapboxGL.StyleSheet.create({ fakeProperty: { idk: "?" } });
}).toThrow();

expect(() => {
MapboxGL.StyleSheet.create({ building: { fakeProperty: 0.84 } });
}).toThrow();
});

it('should throw error for undefined or null style values', () => {
expect(() => {
MapboxGL.StyleSheet.create({ fillOpacity: undefined });
}).toThrow();

expect(() => {
MapboxGL.StyleSheet.create({ fillOpacity: null });
}).toThrow();
});

it('should throw error for passing in undefined or null', () => {
expect(() => MapboxGL.StyleSheet.create()).toThrow();
expect(() => MapboxGL.StyleSheet.create(null)).toThrow();
});

it('should create an identity source function', () => {
expect(MapboxGL.StyleSheet.create({ fillExtrusionHeight: MapboxGL.StyleSheet.identity('height') } )).toEqual({
__MAPBOX_STYLESHEET__: true,
fillExtrusionHeight: {
type: 'function',
payload: {
fn: 'source',
stops: {},
attributeName: 'height',
mode: MapboxGL.InterpolationMode.Identity,
},
},
});
});
});

function verifyStyleSheetsMatch (styles, expectedStyleSheet) {
expect(MapboxGL.StyleSheet.create(styles)).toEqual(expectedStyleSheet);
}

0 comments on commit 3b7ea14

Please sign in to comment.