diff --git a/host-targets-test.js b/host-targets-test.js new file mode 100644 index 0000000..24c8786 --- /dev/null +++ b/host-targets-test.js @@ -0,0 +1,128 @@ +'use strict'; + +let HostTargets = require('./host-targets.js'); + +function parseUa(ua) { + let terms = []; + let parts = ua.split(/\s+/g); + for (let part of parts) { + let _terms = part.split(/\//g); + terms = terms.concat(_terms); + } + let target = {}; + HostTargets.termsToTarget(target, terms); + return target; +} + +function assertField(ua, target, field, expected) { + let actual = target[field]; + if (actual !== expected) { + throw new Error( + `[${field}] expected '${expected}' but got '${actual}' for UA:\n ${ua}`, + ); + } +} + +function testCase(ua, expected) { + let target = parseUa(ua); + for (let [field, value] of Object.entries(expected)) { + assertField(ua, target, field, value); + } +} + +async function main() { + // Cygwin on 32-bit Windows (reports 'gnu') + testCase('webi/curl+wget i686/unknown CYGWIN_NT-10.0-WOW/3.3.5(0.341/5/3) gnu', { + os: 'windows', + arch: 'x86', + vendor: 'pc', + }); + + // Cygwin on 32-bit Windows, legacy curl-only UA + testCase('curl CYGWIN_NT-10.0-WOW/3.3.5(0.341/5/3) i686/unknown gnu', { + os: 'windows', + arch: 'x86', + vendor: 'pc', + }); + + // Cygwin on 64-bit Windows (reports 'libc'), "Cygwin" prefix variant + testCase('webi/curl x86_64/unknown Cygwin/CYGWIN_NT-10.0/3.3.4(0.341/5/3) libc', { + os: 'windows', + arch: 'x86_64', + vendor: 'pc', + }); + + // Cygwin on 64-bit Windows 10 (build 19045) + testCase('webi/curl+wget x86_64/unknown Cygwin/CYGWIN_NT-10.0-19045/3.4.10-1.x86_64 libc', { + os: 'windows', + arch: 'x86_64', + vendor: 'pc', + }); + + // Cygwin on 64-bit Windows 11 (build 26200) — from issue #1083 + testCase('webi/curl+wget x86_64/unknown Cygwin/CYGWIN_NT-10.0-26200/3.4.10-1.x86_64 libc', { + os: 'windows', + arch: 'x86_64', + vendor: 'pc', + }); + + // Cygwin UA with GNU/Linux prefix (webi.sh quirk on some Cygwin installs) + testCase('webi/curl+wget i686/unknown GNU/Linux/CYGWIN_NT-10.0-WOW/3.3.5(0.341/5/3) libc', { + os: 'windows', + arch: 'x86', + vendor: 'pc', + }); + + // MINGW (Git Bash) on 64-bit Windows, webi UA + testCase('webi/curl x86_64/unknown MINGW64_NT-10.0-19045/3.3.6-341.x86_64 libc', { + os: 'windows', + arch: 'x86_64', + vendor: 'pc', + }); + + // MINGW (Git Bash), legacy curl-only UA + testCase('curl MINGW64_NT-10.0-19045/3.3.6-341.x86_64 x86_64/unknown libc', { + os: 'windows', + arch: 'x86_64', + vendor: 'pc', + }); + + // MINGW with Linux prefix in UA path (older Git Bash format) + testCase('curl Linux/MINGW64_NT-10.0-19045/3.3.6-341.x86_64 x86_64/unknown libc', { + os: 'windows', + arch: 'x86_64', + vendor: 'pc', + }); + + // MINGW with Msys prefix (Msys2 variant) + testCase('webi/curl x86_64/unknown Msys/MINGW64_NT-10.0-19045/3.3.6-341.x86_64 libc', { + os: 'windows', + arch: 'x86_64', + vendor: 'pc', + }); + + // Sanity: real Linux should NOT be classified as Windows + testCase('webi/curl+wget x86_64/unknown Linux/6.2.0-1012-aws gnu', { + os: 'linux', + arch: 'x86_64', + vendor: 'unknown', + }); + + // Sanity: Darwin should NOT be classified as Windows + testCase('webi/curl arm64/unknown Darwin/22.6.0', { + os: 'darwin', + arch: 'aarch64', + vendor: 'apple', + }); +} + +main() + .then(function () { + console.error(''); + console.error('PASS'); + process.exit(0); + }) + .catch(function (e) { + console.error(e.stack); + process.exit(1); + }); diff --git a/host-targets.js b/host-targets.js index 90d0267..acb5529 100644 --- a/host-targets.js +++ b/host-targets.js @@ -78,8 +78,8 @@ HostTargets.TERMS = { // OS Android: T.ANDROID, Linux: T.LINUX, - MINGW: T.LINUX, - CYGWIN: T.LINUX, + MINGW: T.WINDOWS, + CYGWIN: T.WINDOWS, Darwin: T.DARWIN, Windows: T.WINDOWS, win32: { os: 'windows', vendor: 'unknown' }, diff --git a/package.json b/package.json index 4f21266..22c4a16 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "build-classifier", - "version": "1.0.3", + "version": "1.0.4", "description": "Determine Host Target Triplet (Arch, Libc, OS, Vendor) from a filenames / download URL and uname / User-Agent strings.", "main": "index.js", "scripts": { "bump": "npm version -m \"chore(release): bump to v%s\"", "fmt": "npm run prettier", "lint": "npm run jshint", - "test": "node lexver-test.js", + "test": "node lexver-test.js && node host-targets-test.js", "----": "------------------------------------", "jshint": "npx -p jshint@2.x -- jshint -c ./.jshintrc --exclude 'node_modules/**/*' *.js", "prettier": "npx -p prettier@3.x -- prettier -w '**/*.{js,md,html}'" diff --git a/uas.json b/uas.json index 18cce1c..14309a0 100644 --- a/uas.json +++ b/uas.json @@ -2046,6 +2046,7 @@ "curl Linux/5.15.131-1-pve x86_64/unknown gnu": 2, "webi/curl+wget x86_64/unknown GNU/Linux/5.10.0-8-amd64 libc": 1, "webi/curl+wget x86_64/unknown Cygwin/CYGWIN_NT-10.0-19045/3.4.10-1.x86_64 libc": 2, + "webi/curl+wget x86_64/unknown Cygwin/CYGWIN_NT-10.0-26200/3.4.10-1.x86_64 libc": 1, "webi/curl+wget x86_64/unknown GNU/Linux/3.10.0-1160.83.1.el7.x86_64 libc": 1, "webi/curl+wget x86_64/unknown GNU/Linux/5.4.250-2.1.ve1.x86_64 libc": 1, "curl Linux/5.4.250-2.1.ve1.x86_64 x86_64/unknown gnu": 1,