test for undocumented colors

This commit is contained in:
Martin Aeschlimann 2018-06-05 16:02:59 +02:00
parent 5b2e81d8b2
commit 2961d2dfc5
6 changed files with 169 additions and 4 deletions

15
scripts/test-release.bat Normal file
View file

@ -0,0 +1,15 @@
@echo off
setlocal
pushd %~dp0\..
:: Endgame tests in AMD
call .\scripts\test.bat --runGlob **\*.releaseTest.js %*
if %errorlevel% neq 0 exit /b %errorlevel%
rmdir /s /q %VSCODEUSERDATADIR%
popd
endlocal

19
scripts/test-release.sh Executable file
View file

@ -0,0 +1,19 @@
#!/bin/bash
set -e
if [[ "$OSTYPE" == "darwin"* ]]; then
realpath() { [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"; }
ROOT=$(dirname $(dirname $(realpath "$0")))
VSCODEUSERDATADIR=`mktemp -d -t 'myuserdatadir'`
else
ROOT=$(dirname $(dirname $(readlink -f $0)))
VSCODEUSERDATADIR=`mktemp -d 2>/dev/null`
fi
cd $ROOT
# Tests in AMD
./scripts/test.sh --runGlob **/*.releaseTest.js "$@"
rm -r $VSCODEUSERDATADIR

View file

@ -20,6 +20,7 @@ export interface ColorContribution {
readonly description: string;
readonly defaults: ColorDefaults;
readonly needsTransparency: boolean;
readonly deprecationMessage: string;
}
@ -87,7 +88,7 @@ class ColorRegistry implements IColorRegistry {
}
public registerColor(id: string, defaults: ColorDefaults, description: string, needsTransparency = false, deprecationMessage?: string): ColorIdentifier {
let colorContribution = { id, description, defaults, needsTransparency };
let colorContribution: ColorContribution = { id, description, defaults, needsTransparency, deprecationMessage };
this.colorsById[id] = colorContribution;
let propertySchema: IJSONSchema = { type: 'string', description, format: 'color-hex', default: '#ff0000' };
if (deprecationMessage) {

View file

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Registry } from 'vs/platform/registry/common/platform';
import { IColorRegistry, Extensions, ColorContribution } from 'vs/platform/theme/common/colorRegistry';
import { editorMarkerNavigationError } from 'vs/editor/contrib/gotoError/gotoErrorWidget';
import { overviewRulerModifiedForeground } from 'vs/workbench/parts/scm/electron-browser/dirtydiffDecorator';
import { STATUS_BAR_DEBUGGING_BACKGROUND } from 'vs/workbench/parts/debug/browser/statusbarColorProvider';
import { debugExceptionWidgetBackground } from 'vs/workbench/parts/debug/browser/exceptionWidget';
import { debugToolBarBackground } from 'vs/workbench/parts/debug/browser/debugActionsWidget';
import { buttonBackground } from 'vs/workbench/parts/welcome/page/electron-browser/welcomePage';
import { embeddedEditorBackground } from 'vs/workbench/parts/welcome/walkThrough/electron-browser/walkThroughPart';
import { request, asText } from 'vs/base/node/request';
import * as pfs from 'vs/base/node/pfs';
import * as path from 'path';
import * as assert from 'assert';
interface ColorInfo {
description: string;
offset: number;
length: number;
}
interface DescriptionDiff {
docDescription: string;
specDescription: string;
}
// add artificial dependencies to some files that are not loaded yet
export const forceColorLoad = [editorMarkerNavigationError, overviewRulerModifiedForeground, STATUS_BAR_DEBUGGING_BACKGROUND,
debugExceptionWidgetBackground, debugToolBarBackground, buttonBackground, embeddedEditorBackground];
export const experimental = []; // 'settings.modifiedItemForeground', 'editorUnnecessary.foreground' ];
suite('Color Registry', function () {
test('all colors documented', async function () {
const reqContext = await request({ url: 'https://raw.githubusercontent.com/Microsoft/vscode-docs/vnext/docs/getstarted/theme-color-reference.md' });
const content = await asText(reqContext);
const expression = /\-\s*\`([\w\.]+)\`: (.*)/g;
let m: RegExpExecArray;
let colorsInDoc: { [id: string]: ColorInfo } = Object.create(null);
while (m = expression.exec(content)) {
colorsInDoc[m[1]] = { description: m[2], offset: m.index, length: m.length };
}
let missing = Object.create(null);
let descriptionDiffs: { [id: string]: DescriptionDiff } = Object.create(null);
let themingRegistry = Registry.as<IColorRegistry>(Extensions.ColorContribution);
for (let color of themingRegistry.getColors()) {
if (!colorsInDoc[color.id]) {
if (!color.deprecationMessage) {
missing[color.id] = getDescription(color);
}
} else {
let docDescription = colorsInDoc[color.id].description;
let specDescription = getDescription(color);
if (docDescription !== specDescription) {
descriptionDiffs[color.id] = { docDescription, specDescription };
}
delete colorsInDoc[color.id];
}
}
let colorsInExtensions = await getColorsFromExtension();
for (let colorId in colorsInExtensions) {
if (!colorsInDoc[colorId]) {
missing[colorId] = colorsInExtensions[colorId];
} else {
delete colorsInDoc[colorId];
}
}
for (let colorId of experimental) {
if (missing[colorId]) {
delete missing[colorId];
}
if (colorsInDoc[colorId]) {
assert.fail(`Color ${colorId} found in doc but marked experimental. Please remove from experimental list.`);
}
}
let undocumentedKeys = Object.keys(missing).map(k => `${k}: ${missing[k]}`);
assert.deepEqual(undocumentedKeys, [], 'Undocumented colors ids');
let superfluousKeys = Object.keys(colorsInDoc);
assert.deepEqual(superfluousKeys, [], 'Colors ids in doc that do not exist');
});
});
function getDescription(color: ColorContribution) {
let specDescription = color.description;
if (color.deprecationMessage) {
specDescription = specDescription + ' ' + color.deprecationMessage;
}
return specDescription;
}
async function getColorsFromExtension(): Promise<{ [id: string]: string }> {
let extPath = require.toUrl('../../../../../../extensions');
let extFolders = await pfs.readDirsInDir(extPath);
let result: { [id: string]: string } = Object.create(null);
for (let folder of extFolders) {
try {
let packageJSON = JSON.parse((await pfs.readFile(path.join(extPath, folder, 'package.json'))).toString());
let contributes = packageJSON['contributes'];
if (contributes) {
let colors = contributes['colors'];
if (colors) {
for (let color of colors) {
let colorId = color['id'];
if (colorId) {
result[colorId] = colorId['description'];
}
}
}
}
} catch (e) {
// ignore
}
}
return result;
}

View file

@ -578,8 +578,8 @@ export class WelcomeInputFactory implements IEditorInputFactory {
// theming
const buttonBackground = registerColor('welcomePage.buttonBackground', { dark: null, light: null, hc: null }, localize('welcomePage.buttonBackground', 'Background color for the buttons on the Welcome page.'));
const buttonHoverBackground = registerColor('welcomePage.buttonHoverBackground', { dark: null, light: null, hc: null }, localize('welcomePage.buttonHoverBackground', 'Hover background color for the buttons on the Welcome page.'));
export const buttonBackground = registerColor('welcomePage.buttonBackground', { dark: null, light: null, hc: null }, localize('welcomePage.buttonBackground', 'Background color for the buttons on the Welcome page.'));
export const buttonHoverBackground = registerColor('welcomePage.buttonHoverBackground', { dark: null, light: null, hc: null }, localize('welcomePage.buttonHoverBackground', 'Hover background color for the buttons on the Welcome page.'));
registerThemingParticipant((theme, collector) => {
const foregroundColor = theme.getColor(foreground);

View file

@ -523,7 +523,7 @@ export class WalkThroughPart extends BaseEditor {
// theming
const embeddedEditorBackground = registerColor('walkThrough.embeddedEditorBackground', { dark: null, light: null, hc: null }, localize('walkThrough.embeddedEditorBackground', 'Background color for the embedded editors on the Interactive Playground.'));
export const embeddedEditorBackground = registerColor('walkThrough.embeddedEditorBackground', { dark: null, light: null, hc: null }, localize('walkThrough.embeddedEditorBackground', 'Background color for the embedded editors on the Interactive Playground.'));
registerThemingParticipant((theme, collector) => {
const color = getExtraColor(theme, embeddedEditorBackground, { dark: 'rgba(0, 0, 0, .4)', extra_dark: 'rgba(200, 235, 255, .064)', light: 'rgba(0,0,0,.08)', hc: null });