airtap-match-browsers
Advanced tools
Comparing version 0.0.1 to 0.0.2
96
index.js
@@ -22,9 +22,9 @@ 'use strict' | ||
// Group by name for faster matching | ||
for (const spec of available) { | ||
const name = lower(spec.name) | ||
for (const manifest of available) { | ||
const name = lower(manifest.name) | ||
if (groups.has(name)) { | ||
groups.get(name).push(spec) | ||
groups.get(name).push(manifest) | ||
} else { | ||
groups.set(name, [spec]) | ||
groups.set(name, [manifest]) | ||
} | ||
@@ -47,2 +47,3 @@ } | ||
let group = groups.get(w.name) || [] | ||
w.version = lower(w.version) | ||
group = filterVersions(group, w.version) | ||
@@ -72,3 +73,3 @@ | ||
// Pick winner by preferredOver rules (or short of that, the last spec) | ||
// Pick winner by preferredOver rules (or short of that, the last manifest) | ||
let winner = alternatives[alternatives.length - 1] | ||
@@ -96,6 +97,6 @@ let max = 0 | ||
// Don't merge options into the spec yet, so that we can | ||
// Don't merge options into the manifest yet, so that we can | ||
// perform fast deduplication by object identity (below). We | ||
// assume that `available` itself doesn't contain duplicates. | ||
matches.push({ spec: winner, options: w.options }) | ||
matches.push({ manifest: winner, options: w.options }) | ||
} | ||
@@ -110,10 +111,10 @@ } | ||
for (let i = 0; i < matches.length; i++) { | ||
const { spec, options } = matches[i] | ||
const { manifest, options } = matches[i] | ||
// Add user-provided options to spec | ||
matches[i] = mergeDeep(spec, { options }) | ||
// Add user-provided options to manifest | ||
matches[i] = mergeDeep(manifest, { options }) | ||
// Remove exact duplicates (same spec, same options) | ||
// Remove exact duplicates (same manifest, same options) | ||
for (let j = i + 1; j < matches.length; j++) { | ||
if (matches[j].spec === spec && | ||
if (matches[j].manifest === manifest && | ||
deepEqual(matches[j].options, options, { strict: true })) { | ||
@@ -126,9 +127,9 @@ matches.splice(j--, 1) | ||
function explode (specs) { | ||
for (let i = 0; i < specs.length; i++) { | ||
const spec = specs[i] | ||
function explode (manifests) { | ||
for (let i = 0; i < manifests.length; i++) { | ||
const manifest = manifests[i] | ||
for (const k of ['version']) { | ||
if (Array.isArray(spec[k])) { | ||
specs.splice(i--, 1, ...spec[k].map(v => ({ ...spec, [k]: v }))) | ||
if (Array.isArray(manifest[k])) { | ||
manifests.splice(i--, 1, ...manifest[k].map(v => ({ ...manifest, [k]: v }))) | ||
break | ||
@@ -140,28 +141,28 @@ } | ||
function withDefaults (spec) { | ||
spec = { ...spec } | ||
function withDefaults (manifest) { | ||
manifest = { ...manifest } | ||
for (const k in defaults) { | ||
spec[k] = spec[k] || defaults[k] | ||
manifest[k] = manifest[k] || defaults[k] | ||
} | ||
if (typeof spec.name !== 'string' || spec.name === '') { | ||
if (typeof manifest.name !== 'string' || manifest.name === '') { | ||
throw new TypeError('Browser "name" is required') | ||
} | ||
spec.name = lower(spec.name) | ||
spec.options = spec.options || {} | ||
manifest.name = lower(manifest.name) | ||
manifest.options = manifest.options || {} | ||
// For airtap < 4 compatibility | ||
// TODO: consider adding a shorthand "device" property for ipad & iphone | ||
if (spec.name === 'iphone' || spec.name === 'ipad') { | ||
const device = spec.name === 'iphone' ? 'iphone simulator' : 'ipad simulator' | ||
const caps = spec.capabilities = { ...spec.capabilities } | ||
if (manifest.name === 'iphone' || manifest.name === 'ipad') { | ||
const device = manifest.name === 'iphone' ? 'iphone simulator' : 'ipad simulator' | ||
const caps = manifest.capabilities = { ...manifest.capabilities } | ||
const appium = caps.appium = { ...caps.appium } | ||
spec.name = 'ios_saf' | ||
manifest.name = 'ios_saf' | ||
appium.deviceName = appium.deviceName || device | ||
} | ||
return spec | ||
return manifest | ||
} | ||
@@ -199,2 +200,3 @@ | ||
} else if (Array.isArray(wanted)) { | ||
// TODO: explode into multiple browsers, instead of this "oneof" behavior | ||
return wanted.some(el => match(available, el, explicit, skip, key)) | ||
@@ -240,15 +242,15 @@ } else if (isObject(wanted)) { | ||
// Assumes specs are sorted by version. | ||
function filterVersions (specs, version) { | ||
const [gte, lte] = range(version, specs) | ||
// Assumes manifests are sorted by version. | ||
function filterVersions (manifests, version) { | ||
const [gte, lte] = range(version, manifests) | ||
let start = 0 | ||
let end = specs.length | ||
let end = manifests.length | ||
if (gte) { | ||
while (start < end && cmpVersion(specs[start].version, gte) < 0) { | ||
while (start < end && cmpVersion(manifests[start].version, gte) < 0) { | ||
start++ | ||
} | ||
if (!matchVersion(gte, specs[start] && specs[start].version)) { | ||
if (!matchVersion(gte, manifests[start] && manifests[start].version)) { | ||
throw new Error(`Version not found: ${gte}`) | ||
@@ -259,7 +261,7 @@ } | ||
if (lte) { | ||
while (end > start && cmpVersion(specs[end - 1].version, lte) > 0) { | ||
while (end > start && cmpVersion(manifests[end - 1].version, lte) > 0) { | ||
end-- | ||
} | ||
if (!matchVersion(lte, specs[end - 1] && specs[end - 1].version)) { | ||
if (!matchVersion(lte, manifests[end - 1] && manifests[end - 1].version)) { | ||
throw new Error(`Version not found: ${lte}`) | ||
@@ -269,6 +271,6 @@ } | ||
return specs.slice(start, end) | ||
return manifests.slice(start, end) | ||
} | ||
function range (version, specs) { | ||
function range (version, manifests) { | ||
const arr = version.split('..') | ||
@@ -281,6 +283,6 @@ | ||
return arr.map(function (v) { | ||
if (!specs.length) return | ||
if (v === 'oldest') return specs[0].version | ||
if (v === 'latest') return latest(specs, 0) | ||
if (!isNaN(v) && v < 0) return latest(specs, v * -1) | ||
if (!manifests.length) return | ||
if (v === 'oldest') return manifests[0].version | ||
if (v === 'latest') return latest(manifests, 0) | ||
if (!isNaN(v) && v < 0) return latest(manifests, v * -1) | ||
@@ -291,10 +293,10 @@ return v | ||
function latest (specs, n) { | ||
for (let i = specs.length - 1; i >= 0; i--) { | ||
if (!isBeta(specs[i].version) && !n--) { | ||
return specs[i].version | ||
function latest (manifests, n) { | ||
for (let i = manifests.length - 1; i >= 0; i--) { | ||
if (!isBeta(manifests[i].version) && !n--) { | ||
return manifests[i].version | ||
} | ||
} | ||
return specs[0].version | ||
return manifests[0].version | ||
} | ||
@@ -301,0 +303,0 @@ |
{ | ||
"name": "airtap-match-browsers", | ||
"version": "0.0.1", | ||
"description": "Match browsers in Airtap 4 format", | ||
"version": "0.0.2", | ||
"description": "Match browser manifests to a desired set of browsers", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "author": "Vincent Weevers", |
# airtap-match-browsers | ||
> **Match browsers in Airtap 4 format.** | ||
> **Match [browser manifests](https://github.com/airtap/browser-manifest) to a desired set of browsers.** | ||
> Intended to replace [`sauce-browsers`](https://github.com/lpinca/sauce-browsers) in conjunction with [`airtap-sauce-browsers`](https://github.com/airtap/sauce-browsers). | ||
@@ -17,6 +17,6 @@ | ||
// A list of browsers available on Sauce Labs | ||
// Browsers available on Sauce Labs, as manifests | ||
const available = await sauce() | ||
// A list of browsers that we want | ||
// Browsers that we want, by manifest properties | ||
const wanted = [ | ||
@@ -28,4 +28,4 @@ { name: 'firefox', platform: 'linux' }, | ||
// Select browsers | ||
const specs = match(available, wanted) | ||
// Find matches | ||
const manifests = match(available, wanted) | ||
``` | ||
@@ -45,3 +45,3 @@ | ||
- A keyword, one of "oldest" (first version) or "latest" (last numeric version). | ||
- A range in the form of `<start>..<end>`, where `start` and `end` are either a version or a keyword. | ||
- A range in the form of `<start>..<end>`, where `start` and `end` are either a version or a keyword. This will result in one or more matches. | ||
- A negative range in the form of `-<n>..latest`, for example `-1..latest` which means the last 2 numeric versions. | ||
@@ -51,3 +51,3 @@ - A non-numeric version like "dev" and "beta". Such versions sort after numeric versions, so that `oldest..latest` excludes "dev" and `latest..dev` includes latest, "beta" and "dev". | ||
If a version is not found (including in ranges), an error is thrown. | ||
If a version is not found (including the start and end of ranges) an error is thrown. | ||
@@ -59,3 +59,3 @@ ### `platform` and any other (nested) property | ||
```js | ||
const specs = match(available, [{ | ||
const manifests = match(available, [{ | ||
name: 'chrome for android', | ||
@@ -62,0 +62,0 @@ version: '10', |
12807
247