Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: split the main file into 3 #514

Merged
merged 3 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Current Test File",
"autoAttachChildProcesses": true,
"skipFiles": ["<node_internals>/**", "**/node_modules/**"],
"program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
"args": ["run", "${relativeFile}"],
"smartStep": true,
"console": "integratedTerminal"
}
]
}
13 changes: 0 additions & 13 deletions src/browser-detection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { describe, expect, test } from 'vitest';

import {
detectBrowserName,
detectBrowserVersion,
detectBrowserNameAndVersion,
} from './browser-detection';

Expand Down Expand Up @@ -211,15 +210,3 @@ describe('Should correctly detect name of', () => {
expect(detectBrowserName(chrome)).toEqual('Chrome');
});
});

describe('Should correctly detect version of', () => {
test('UC Browser', () => {
const ucBrowser = {
userAgent: `UCWEB/2.0 (Java; U; MIDP-2.0; Nokia203/20.37)
U2/1.0.0 UCBrowser/8.7.0.218 U2/1.0.0 Mobile`,
};
const name = 'UC Browser';

expect(detectBrowserVersion(ucBrowser, name)).toEqual(8.7);
});
});
56 changes: 2 additions & 54 deletions src/browser-detection.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { retrieveVersion } from './retrieve-version';

import { detectBrowserVersion } from './detect-browser-version';
/**
* Detects Chrome browser
*/
Expand Down Expand Up @@ -154,7 +153,7 @@ export type UaBrowserName =
/**
* Returns Association
*/
function getBrowserUaName(
export function getBrowserUaName(
name: BrowserName | undefined,
): UaBrowserName | undefined {
if (name) {
Expand All @@ -173,57 +172,6 @@ function getBrowserUaName(
}
}

/**
* Detects browser version
*/
function detectBrowserVersion(
nav: {
userAgent: string;
appName?: string;
appVersion?: string;
},
name: BrowserName | undefined,
): number | undefined {
const { userAgent } = nav;

if (name) {
// eslint-disable-next-line default-case, @typescript-eslint/switch-exhaustiveness-check
switch (name) {
case 'Edge': {
const temp = /\b(Edge)\/(\d+)/.exec(userAgent);
return temp ? Number(temp[2]) : undefined;
}

case 'IE': {
const temp = /\brv[ :]+(\d+)/g.exec(userAgent) ?? [];
return Number(temp[1]) || undefined;
}
}
}

const browserName = getBrowserUaName(name);

if (browserName) {
return retrieveVersion(browserName, userAgent);
}

let found =
/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i.exec(
userAgent,
) ?? [];

// eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error
// @ts-ignore
found = found[2] ? [found[1], found[2]] : [nav.appName, nav.appVersion, '-?'];

let temp;
if ((temp = /version\/(\d+)/i.exec(userAgent)) !== null) {
found.splice(1, 1, temp[1]);
}

return found[1] ? Number(found[1]) : undefined;
}

/**
* Detects browser name & version
*/
Expand Down
185 changes: 185 additions & 0 deletions src/detect-browser-version.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/* eslint-disable no-warning-comments */
import { describe, expect, test } from 'vitest';

import { detectBrowserVersion } from './detect-browser-version';

describe('Should correctly detect name & version of', () => {
test('Chrome', () => {
const chrome = {
userAgent: `Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/62.0.3202.94 Safari/537.36`,
};

expect(detectBrowserVersion(chrome, 'Chrome')).toStrictEqual(62);

const chromeMobile = {
userAgent: `Mozilla/5.0 (Linux; Android 6.0;
Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36`,
};

expect(detectBrowserVersion(chromeMobile, 'Chrome')).toStrictEqual(62);
});

test('Safari 17', () => {
const safari = {
userAgent: `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15`,
};

expect(detectBrowserVersion(safari, 'Safari')).toStrictEqual(17);
});

test('Safari', () => {
const safari = {
userAgent: `Mozilla/5.0 (Macintosh;
Intel Mac OS X 10_13_1) AppleWebKit/604.3.5 (KHTML, like Gecko)
Version/11.0.1 Safari/604.3.5`,
};

expect(detectBrowserVersion(safari, 'Safari')).toStrictEqual(11);
});

test('Safari iPad', () => {
const safari = {
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15',
};
expect(detectBrowserVersion(safari, 'Safari')).toStrictEqual(17);
});

test('Samsung Internet', () => {
const samsung = {
userAgent: `Mozilla/5.0 (Linux; Android 5.1.1;
SAMSUNG SM-G360T1 Build/LMY47X)
AppleWebKit/537.36 (KHTML, like Gecko)
SamsungBrowser/3.3 Chrome/38.0.2125.102 Mobile Safari/537.36`,
};

expect(detectBrowserVersion(samsung, 'Samsung Internet')).toStrictEqual(3);
});

test('UC Browser', () => {
const ucBrowser = {
userAgent: `UCWEB/2.0 (Java; U; MIDP-2.0; Nokia203/20.37)
U2/1.0.0 UCBrowser/8.7.0.218 U2/1.0.0 Mobile`,
};

expect(detectBrowserVersion(ucBrowser, 'UC Browser')).toStrictEqual(8.7);

const ucBrowser11 = {
userAgent: `Mozilla/5.0 (Linux; U; Android 4.2.2; en-US;
Micromax A102 Build/MicromaxA102) AppleWebKit/534.30
(KHTML, like Gecko) Version/4.0 UCBrowser/11.1.0.882 U3/0.8.0
Mobile Safari/534.30`,
};

expect(detectBrowserVersion(ucBrowser11, 'UC Browser')).toStrictEqual(11);
});

test('Firefox', () => {
const firefox = {
userAgent: `Mozilla/5.0
(Windows NT 10.0; Win64; x64; rv:57.0)
Gecko/20100101 Firefox/57.0`,
};

expect(detectBrowserVersion(firefox, 'Firefox')).toStrictEqual(57);
});

test('QQ Browser', () => {
const qqbrowser = {
userAgent: `Mozilla/5.0 (Linux; U; Android 11; zh-cn; 21091116UC Build/RP1A.200720.011)
AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0
Chrome/66.0.3359.126 MQQBrowser/10.8 Mobile Safari/537.36`,
};
// TODO: change from 10 to 10.8
expect(detectBrowserVersion(qqbrowser, 'QQ Browser')).toStrictEqual(10);
});

describe('Opera', () => {
test('Blink-based', () => {
const opera = {
userAgent: `Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/62.0.3202.89 Safari/537.36 OPR/49.0.2725.39`,
};

expect(detectBrowserVersion(opera, 'Opera')).toStrictEqual(49);
});
});

test('Android browser', () => {
const android = {
userAgent: `Mozilla/5.0 (Linux; U; Android 4.0.4;
pt-br; MZ608 Build/7.7.1-141-7-FLEM-UMTS-LA)
AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30`,
};

expect(detectBrowserVersion(android, 'Android Browser')).toStrictEqual(4);
});

test('Edge', () => {
const edge = {
userAgent: `Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063`,
};

expect(detectBrowserVersion(edge, 'Edge')).toStrictEqual(15);
});

test('Internet Explorer', () => {
const ie = {
userAgent: `Mozilla/5.0 (Windows NT 10.0; WOW64;
Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727;
.NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko`,
};

expect(detectBrowserVersion(ie, 'IE')).toStrictEqual(11);
});
});

describe('Should not fail', () => {
test('If can not find a version', () => {
const ieWithoutVersion = {
userAgent: `Mozilla/5.0 (Windows NT 10.0; WOW64;
Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727;
.NET CLR 3.0.30729; .NET CLR 3.5.30729) like Gecko`,
};

expect(detectBrowserVersion(ieWithoutVersion, 'IE')).toEqual(undefined);
});

test('if user agent is invalid', () => {
const emptyUserAgent = {
userAgent: '',
};

expect(detectBrowserVersion(emptyUserAgent, undefined)).toEqual(undefined);
});
});

describe('Should correctly detect name of', () => {
test('Chrome', () => {
const chrome = {
userAgent: `Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/62.0.3202.94 Safari/537.36`,
};

expect(detectBrowserVersion(chrome, 'Chrome')).toEqual(62);
});
});

describe('Should correctly detect version of', () => {
test('UC Browser', () => {
const ucBrowser = {
userAgent: `UCWEB/2.0 (Java; U; MIDP-2.0; Nokia203/20.37)
U2/1.0.0 UCBrowser/8.7.0.218 U2/1.0.0 Mobile`,
};

expect(detectBrowserVersion(ucBrowser, 'UC Browser')).toEqual(8.7);
});
});
55 changes: 55 additions & 0 deletions src/detect-browser-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { retrieveVersion } from './retrieve-version';
import { getBrowserUaName } from './browser-detection';

import type { BrowserName } from './browser-detection';

/**
* Detects browser version
*/
export function detectBrowserVersion(
nav: {
userAgent: string;
appName?: string;
appVersion?: string;
},
name: BrowserName | undefined,
): number | undefined {
const { userAgent } = nav;

if (name) {
// eslint-disable-next-line default-case, @typescript-eslint/switch-exhaustiveness-check
switch (name) {
case 'Edge': {
const temp = /\b(Edge)\/(\d+)/.exec(userAgent);
return temp ? Number(temp[2]) : undefined;
}

case 'IE': {
const temp = /\brv[ :]+(\d+)/g.exec(userAgent) ?? [];
return Number(temp[1]) || undefined;
}
}
}

const browserName = getBrowserUaName(name);

if (browserName) {
return retrieveVersion(browserName, userAgent);
}

let found =
/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i.exec(
userAgent,
) ?? [];

// eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error
// @ts-ignore
found = found[2] ? [found[1], found[2]] : [nav.appName, nav.appVersion, '-?'];

let temp;
if ((temp = /version\/(\d+)/i.exec(userAgent)) !== null) {
found.splice(1, 1, temp[1]);
}

return found[1] ? Number(found[1]) : undefined;
}
12 changes: 12 additions & 0 deletions src/retrieve-version.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { describe, expect, test } from 'vitest';

import { retrieveVersion } from './retrieve-version';

describe('Should correctly eject browser version from string', () => {
test('Opera', () => {
const userAgent = `Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/62.0.3202.89 Safari/537.36 OPR/49.0.2725.39`;
expect(retrieveVersion('OPR', userAgent)).toEqual(49);
});
});
Loading