blob: 9847cbcd3de5172009d90f0481c7cf7b42565fc1 [file]
/* This file is a part of @mdn/browser-compat-data
* See LICENSE file for more information. */
/** @import {CompatStatement} from '../../types/types.js' */
import assert from 'node:assert/strict';
import { Logger } from '../utils.js';
import test, {
checkExperimental,
standardTrackExceptions,
} from './test-status.js';
describe('checkExperimental', () => {
it('should return true when data is not experimental', () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: false,
standard_track: true,
deprecated: false,
},
support: {},
};
assert.equal(checkExperimental(data), true);
});
it('should return true when data is experimental but supported by only one engine', () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: true,
standard_track: true,
deprecated: false,
},
support: {
firefox: {
version_added: '1',
},
chrome: {
version_added: 'preview',
},
},
};
assert.equal(checkExperimental(data), true);
});
it('should return false when data is experimental and supported by more than one engine', () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: true,
standard_track: true,
deprecated: false,
},
support: {
firefox: {
version_added: '1',
},
chrome: {
version_added: '1',
},
},
};
assert.equal(checkExperimental(data), false);
});
it('should ignore non-relevant browsers when determining experimental status', () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: true,
standard_track: true,
deprecated: false,
},
support: {
// Bun and Deno are not part of the Core browser set.
firefox: {
version_added: '1',
},
bun: {
version_added: '1.0',
},
deno: {
version_added: '1.0',
},
},
};
assert.equal(checkExperimental(data), true);
});
});
describe('checkStatus', () => {
/** @type {Logger} */
let logger;
beforeEach(() => {
logger = new Logger('test', 'test');
});
it('should not log error when status is not defined', async () => {
/** @type {CompatStatement} */
const data = {
status: undefined,
support: {},
};
await test.check(logger, {
data,
path: { full: 'api.Test', category: 'api' },
});
assert.equal(logger.messages.length, 0);
});
it('should log error when category is webextensions and status is defined', async () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: false,
standard_track: false,
deprecated: false,
},
support: {},
};
await test.check(logger, {
data,
path: { full: 'webextensions.Test', category: 'webextensions' },
});
assert.equal(logger.messages.length, 1);
assert.ok(logger.messages[0].message.includes('not allowed'));
});
it('should log error when status is both experimental and deprecated', async () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: true,
standard_track: false,
deprecated: true,
},
support: {},
};
await test.check(logger, {
data,
path: { full: 'api.Test', category: 'api' },
});
assert.equal(logger.messages.length, 1);
assert.ok(logger.messages[0].message.includes('Unexpected simultaneous'));
});
it('should log error when status is non-standard but has a spec_url', async () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: false,
standard_track: false,
deprecated: false,
},
spec_url: 'https://example.com',
support: {},
};
await test.check(logger, {
data,
path: { full: 'api.Test', category: 'api' },
});
assert.equal(logger.messages.length, 1);
assert.ok(logger.messages[0].message.includes('but has a'));
});
it('should log error when status is standard_track but missing spec_url', async () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: false,
standard_track: true,
deprecated: false,
},
support: {},
};
await test.check(logger, {
data,
path: { category: 'api', full: 'api.NewFeature' },
});
assert.equal(logger.messages.length, 1);
assert.ok(logger.messages[0].message.includes('missing required'));
});
it('should log error when status is experimental and supported by more than one engine', async () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: true,
standard_track: false,
deprecated: false,
},
support: {
firefox: {
version_added: '1',
},
chrome: {
version_added: '1',
},
},
};
await test.check(logger, {
data,
path: { full: 'api.Test', category: 'api' },
});
assert.equal(logger.messages.length, 1);
assert.ok(logger.messages[0].message.includes('should be set to'));
});
describe('standard-track-exceptions', () => {
beforeEach(() => {
standardTrackExceptions.add('api.Foo');
});
afterEach(() => {
standardTrackExceptions.delete('api.Foo');
});
it('should not log error for features in exception list missing spec_url', async () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: false,
standard_track: true,
deprecated: false,
},
support: {},
};
await test.check(logger, {
data,
path: { category: 'api', full: 'api.Foo' },
});
// Feature is in the exception list.
assert.equal(logger.messages.length, 0);
});
it('should log warning when exception no longer applies (has spec_url)', async () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: false,
standard_track: true,
deprecated: false,
},
spec_url: 'https://example.com/spec',
support: {},
};
await test.check(logger, {
data,
path: { category: 'api', full: 'api.Foo' },
});
// Feature is in the exception list but now has `spec_url`.
assert.equal(logger.messages.length, 1);
assert.equal(logger.messages[0].level, 'warning');
assert.ok(logger.messages[0].message.includes('exception list'));
});
it('should log warning when exception no longer applies (standard_track false)', async () => {
/** @type {CompatStatement} */
const data = {
status: {
experimental: false,
standard_track: false,
deprecated: false,
},
support: {},
};
await test.check(logger, {
data,
path: { category: 'api', full: 'api.Foo' },
});
// Feature is in the exception list but `standard_track` is now false.
assert.equal(logger.messages.length, 1);
assert.equal(logger.messages[0].level, 'warning');
assert.ok(logger.messages[0].message.includes('exception list'));
});
});
});