From 11216b53023230a3ccb5be82214c38e695291c21 Mon Sep 17 00:00:00 2001 From: Luis Flores Date: Tue, 14 Feb 2017 15:48:57 +0000 Subject: [PATCH] Add 100% test coverage --- .gitignore | 3 ++ package.json | 14 +++++--- src/index.js | 25 ++++++------- test/index.test.js | 89 +++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 103 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index f553757..43cd5f8 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ # node_modules/ npm-debug.log + +# Jest coverage +coverage/ \ No newline at end of file diff --git a/package.json b/package.json index 301ba45..3054e46 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,17 @@ "test": "jest" }, "jest": { - "preset": "react-native" + "preset": "react-native", + "collectCoverage": true, + "coverageThreshold": { + "global": { + "branches": 100, + "functions": 100, + "lines": 100, + "statements": 100 + } + } }, - "transformIgnorePatterns": [ - "node_modules/(?!react-native|my-project|react-native-button)" - ], "author": "Luis Flores (http://luisflores.mx/)", "license": "MIT", "dependencies": { diff --git a/src/index.js b/src/index.js index 1d0f7e9..953d1ea 100644 --- a/src/index.js +++ b/src/index.js @@ -9,7 +9,7 @@ const fetchQueries = (expression) => { let match; while (match = regex.exec(expression)) { - if (match && match[0]) { + if (match && match[0] && match[1]) { queries.push(match[0]); } } @@ -26,7 +26,7 @@ const execRegex = (queries, expression, path) => { const queryRegex = new RegExp(regexExpression, 'g'); const match = queryRegex.exec(path); - if (match) { + if (match && !match[1].includes('/')) { let results = { path: match[0] } queries.forEach((query, index) => { const id = query.substring(1); @@ -39,16 +39,6 @@ const execRegex = (queries, expression, path) => { return false; }; -const evaluateRoute = (expression, path) => { - const queries = fetchQueries(expression); - - if (queries.length) { - return execRegex(queries, expression, path); - } - - return false; -}; - const evaluateExpression = (expression, path, scheme) => { if (expression === path) { return { scheme, path }; @@ -64,7 +54,10 @@ const evaluateExpression = (expression, path, scheme) => { } if (typeof expression === 'string' && expression.includes(':')) { - return evaluateRoute(expression, path); + const queries = fetchQueries(expression); + if (queries.length) { + return execRegex(queries, expression, path); + } } return false; @@ -102,10 +95,12 @@ const addScheme = (scheme) => { }; const handleUrl = ({ url }) => { - Linking.canOpenURL(url).then((supported) => { + return Linking.canOpenURL(url).then((supported) => { if (supported) { - evaluateUrl(url); + evaluateUrl(url); } + + return Promise.resolve(supported); }); }; diff --git a/test/index.test.js b/test/index.test.js index bd5e545..c883ce8 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,5 +1,7 @@ import DeepLinking, { evaluateUrl } from '../src'; +DeepLinking.addScheme('domain://'); + describe('DeepLinking', () => { const articleRoute = { expression: 'domain://article', @@ -10,14 +12,16 @@ describe('DeepLinking', () => { expression: 'domain://music', callback: () => {}, }; - + + beforeEach(() => { + expect(DeepLinking.routes).toEqual([]); + }); + afterEach(() => { DeepLinking.resetRoutes(); }); test('addRoute', () => { - expect(DeepLinking.routes).toEqual([]); - DeepLinking.addRoute(articleRoute.expression, articleRoute.callback); expect(DeepLinking.routes).toEqual([articleRoute]); @@ -26,8 +30,6 @@ describe('DeepLinking', () => { }); test('removeRoute', () => { - expect(DeepLinking.routes).toEqual([]); - DeepLinking.addRoute(articleRoute.expression, articleRoute.callback); DeepLinking.addRoute(musicRoute.expression, musicRoute.callback); expect(DeepLinking.routes).toEqual([articleRoute, musicRoute]); @@ -37,8 +39,6 @@ describe('DeepLinking', () => { }); test('resetRoutes', () => { - expect(DeepLinking.routes).toEqual([]); - DeepLinking.addRoute(articleRoute.expression, articleRoute.callback); DeepLinking.addRoute(musicRoute.expression, musicRoute.callback); expect(DeepLinking.routes).toEqual([articleRoute, musicRoute]); @@ -46,11 +46,31 @@ describe('DeepLinking', () => { DeepLinking.resetRoutes(); expect(DeepLinking.routes).toEqual([]); }); + + test('handleUrl supported url', () => { + jest.resetModules(); + jest.mock('Linking', () => ({ + canOpenURL: jest.fn(() => Promise.resolve(true)), + })); + + return DeepLinking.handleUrl({ url: '' }).then(supported => { + expect(supported).toEqual(true); + }); + }); + + test('handleUrl unsupported url', () => { + jest.resetModules(); + jest.mock('Linking', () => ({ + canOpenURL: jest.fn(() => Promise.resolve(false)), + })); + + return DeepLinking.handleUrl({ url: '' }).then(supported => { + expect(supported).toEqual(false); + }); + }); }); describe('Routes', () => { - DeepLinking.addScheme('domain://'); - afterEach(() => { DeepLinking.resetRoutes(); }); @@ -157,4 +177,55 @@ describe('Routes', () => { evaluateUrl('domain://music/123/details'); expect(urlEvaluated).toEqual(true); }); + + test('invalid scheme something://music', () => { + let urlEvaluated = false; + DeepLinking.addRoute('/music', () => { + urlEvaluated = true; + }); + + evaluateUrl('something://music'); + expect(urlEvaluated).toEqual(false); + }); + + test('invalid route', () => { + let urlEvaluated = false; + DeepLinking.addRoute('music', () => { + urlEvaluated = true; + }); + + evaluateUrl('domain://music'); + expect(urlEvaluated).toEqual(false); + }); + + test('invalid path', () => { + let urlEvaluated = false; + DeepLinking.addRoute('/music/:id', (response) => { + urlEvaluated = true; + }); + + evaluateUrl('domain://music/12/details'); + expect(urlEvaluated).toEqual(false); + }); + + test('invalid query', () => { + let urlEvaluated = false; + DeepLinking.addRoute('/music/:', () => { + urlEvaluated = true; + }); + + evaluateUrl('domain://music/1'); + expect(urlEvaluated).toEqual(false); + }); + + test('invalid path with regex domain://music/(.*)\/details/', () => { + let urlEvaluated = false; + const regex = /\/music\/(.*)\/details/g; + DeepLinking.addRoute(regex, (wtf) => { + urlEvaluated = true; + }); + + evaluateUrl('domain://videos/123/details'); + expect(urlEvaluated).toEqual(false); + }); });