| /* 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')); |
| }); |
| }); |
| }); |