diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..12803c44 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,27 @@ +# Change Log +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [0.2.0] - 2017.01.25 +### Added +- Queue class for queuing document update + +### Fixed +- Colored background update + +## [0.1.2] (2017.01.18) +### Fixed +- Colored background update + +## [0.1.1] (2017.01.18) +### Changed +- Logo less pixelated +- README + +## [0.1.0] (2017.01.17) +### Added +- Regex matching css hexa colors +- Colored background generation +- Colored background update diff --git a/README.md b/README.md index bf9d94f4..cbbef49c 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # Colorize -[![codebeat badge](https://codebeat.co/badges/71c89f96-3953-49b5-a5ae-8f40ad1359fd)](https://codebeat.co/projects/github-com-kamikillerto-vscode_colorize) -[![Build Status](https://travis-ci.org/KamiKillertO/vscode_colorize.svg?branch=master)](https://travis-ci.org/KamiKillertO/vscode_colorize) -[![Build status](https://ci.appveyor.com/api/projects/status/errygb6n97kiq75a?svg=true)](https://ci.appveyor.com/project/KamiKillertO/vscode-colorize) -[![Licence](https://img.shields.io/github/license/KamiKillertO/vscode_colorize.svg)](https://github.com/KamiKillertO/vscode_colorize) -![VS Code Marketplace](http://vsmarketplacebadge.apphb.com/version-short/kamikillerto.vscode-colorize.svg) +[![codebeat badge](https://codebeat.co/badges/71c89f96-3953-49b5-a5ae-8f40ad1359fd)](https://codebeat.co/projects/github-com-kamikillerto-vscode_colorize) [![Build Status](https://travis-ci.org/KamiKillertO/vscode_colorize.svg?branch=master)](https://travis-ci.org/KamiKillertO/vscode_colorize) [![Build status](https://ci.appveyor.com/api/projects/status/errygb6n97kiq75a?svg=true)](https://ci.appveyor.com/project/KamiKillertO/vscode-colorize) [![Licence](https://img.shields.io/github/license/KamiKillertO/vscode_colorize.svg)](https://github.com/KamiKillertO/vscode_colorize) ![VS Code Marketplace](http://vsmarketplacebadge.apphb.com/version-short/kamikillerto.vscode-colorize.svg) Instantly visualize your css colors @@ -24,11 +20,16 @@ Calling out known issues can help limit users opening duplicate issues against y ## Release Notes -## Latest 0.1.2 (2017.01.18) +### Latest 0.2.0 (2017.01.25) + +- Huge code refacto +- Dramatically improvement colored background updates + +### 0.1.2 (2017.01.18) - Fix background update -## 0.1.1 (2017.01.18) +### 0.1.1 (2017.01.18) - README update - Update logo @@ -51,6 +52,7 @@ See [CHANGELOG](CHANGELOG.md) for more information. - [ ] Generate background for hsla colors - [ ] Generate background for Predefined/Cross-browser colors - [ ] Generate background for preprocessor variables +- [ ] Generate background for css variables ## Contributing diff --git a/assets/demo.gif b/assets/demo.gif index 1ebf9be8..fe2c6e40 100644 Binary files a/assets/demo.gif and b/assets/demo.gif differ diff --git a/package.json b/package.json index dfd9987a..f364512d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "vscode-colorize", "displayName": "colorize", "description": "A vscode extension to help visualize css colors in files.", - "version": "0.1.2", + "version": "0.2.0", "publisher": "kamikillerto", "license": "Apache-2.0", "icon": "assets/logo.png", @@ -21,7 +21,7 @@ "preprocessor" ], "galleryBanner": { - "theme": "dark" + "theme": "light" }, "activationEvents": [ "onLanguage:css", @@ -38,8 +38,7 @@ }, "homepage": "https://github.com/KamiKillertO/vscode_colorize", "repository": { - "type": "git", - "url": "https://github.com/KamiKillertO/vscode_colorize" + "url": "https://github.com/KamiKillertO/vscode_colorize.git" }, "scripts": { "vscode:prepublish": "tsc -p ./", diff --git a/src/color-decoration.ts b/src/color-decoration.ts new file mode 100644 index 00000000..730908f5 --- /dev/null +++ b/src/color-decoration.ts @@ -0,0 +1,54 @@ +import { + TextEditor, + Range, + TextEditorDecorationType, + Position, + window +} from 'vscode'; + +import ColorUtil from './color-util'; +import Color from './color' + +class ColorDecoration { + public color: Color; + public textPosition: Range; + public decoration: TextEditorDecorationType; + public disposed: boolean = false; + + public constructor(textPosition: Range, color: Color) { + this.textPosition = textPosition; + this.color = color; + this._generateDecorator(); + } + + private _updateDecoration(editor) { + this.decoration.dispose(); + this.decoration = this._generateDecorator(); + editor.setDecorations(this.decoration, [{ + range: this.textPosition + }]); + } + public dispose(): void { + this.decoration.dispose(); + } + + private _generateDecorator(): TextEditorDecorationType { + let textColor = null; + let luminance = ColorUtil.luminance(this.color); + if (luminance < 0.7) { + textColor = '#fff'; + } else { + textColor = '#000'; + } + let backgroundDecorationType = window.createTextEditorDecorationType({ + borderWidth: "1px", + borderStyle: "solid", + borderColor: this.color.value, + backgroundColor: this.color.value, + color: textColor + }); + this.decoration = backgroundDecorationType; + return backgroundDecorationType; + } +} +export default ColorDecoration; diff --git a/src/color-util.ts b/src/color-util.ts index f05a6c84..5f898f2c 100644 --- a/src/color-util.ts +++ b/src/color-util.ts @@ -1,10 +1,11 @@ import { HEXA_COLOR } from './color-regex'; +import Color from './color'; -const ColorUtil = { - getRGB(color: string): number[] { +class ColorUtil { + public static getRGB(color: Color): number[] { let rgb: any[] = []; - if (color.match(HEXA_COLOR)) { - rgb = /#(.+)/gi.exec(color); + if (color.model === 'hexa') { + rgb = /#(.+)/gi.exec(color.value); if (rgb[1].length === 3) { return rgb[1].split('').map(_ => parseInt(_ + _, 16)); } @@ -12,9 +13,9 @@ const ColorUtil = { return [16 * rgb[0] + rgb[1], 16 * rgb[2] + rgb[3], 16 * rgb[4] + rgb[5]]; } return []; - }, + } - luminance(color: string): number { + public static luminance(color: Color): number { let rgb = this.getRGB(color); if (!rgb) { return null; @@ -31,5 +32,29 @@ const ColorUtil = { }); return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]; } + + public static extractColor(text: string):Color[] { + let colors:Color[] = []; + colors = colors.concat(this._extractHexa(text)); + return colors; + } + + public static match(text: string, model: string):boolean { + switch(model) { + case 'hexa': + return !!text.match(HEXA_COLOR); + default: + return false; + } + } + + private static _extractHexa(text: string): Color[] { + let match = null; + let colors:Color[] = []; + while((match = HEXA_COLOR.exec(text)) !== null) { + colors.push(new Color('hexa', match[1], match.index)) + } + return colors; + } }; export default ColorUtil; diff --git a/src/color.ts b/src/color.ts new file mode 100644 index 00000000..dc2c0e70 --- /dev/null +++ b/src/color.ts @@ -0,0 +1,14 @@ +import ColorUtil from './color-util'; + +class Color { + public model: string; + public value: string; + public positionInText: number; + + public constructor(model: string, value: string, positionInText: number = 0) { + this.model = model; + this.value = value; + this.positionInText = positionInText; + } +} +export default Color; diff --git a/src/extension.ts b/src/extension.ts index d8df4f12..0c204659 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -13,140 +13,249 @@ import { TextEditorDecorationType, TextDocument, TextLine, - Position + Position, + TextDocumentChangeEvent, + TextDocumentContentChangeEvent } from 'vscode'; import { HEXA_COLOR } from './color-regex'; import ColorUtil from './color-util'; +import ColorDecoration from './color-decoration'; +import Color from './color'; +import Queue from './queue'; // this method is called when your extension is activated // your extension is activated the very first time the command is executed -let decorations: ColorDecoration[] = []; - -export function activate(context: ExtensionContext) { - let timeout = null; - let editor = window.activeTextEditor; +function mapToArray(map: Map) { + let it = map.keys() + let tmp = it.next(); + let array= []; + while(!tmp.done) { + array.push(tmp.value); + tmp= it.next(); + } + return array; +}; +function generateTextDocumentContentChange(startLine: number, text: string): TextDocumentContentChangeEvent { + return { + rangeLength: 0, + text: text, + range: new Range(new Position(startLine, 0), new Position(startLine, 0)) + }; +} +function mutEditedLIneForDeletion(editedLine: TextDocumentContentChangeEvent[]): TextDocumentContentChangeEvent[] { - function triggerUpdateDecorations( /*range*/ ) { - if (timeout) { - clearTimeout(timeout); + let newEditedLine: TextDocumentContentChangeEvent[] = []; + let startLine = 0; + let before = 0; + editedLine.reverse(); + editedLine.forEach(line => { + startLine = line.range.start.line + before; + for (let i = line.range.start.line; i <= line.range.end.line; i++) { + newEditedLine.push(generateTextDocumentContentChange(startLine, line.text)); + before--; } + before++; + }); + return newEditedLine.reverse(); +} +function mutEditedLIne(editedLine: TextDocumentContentChangeEvent[]): TextDocumentContentChangeEvent[] { + let newEditedLine: TextDocumentContentChangeEvent[] = []; + let startLine = 0; + let before = 0; + editedLine.reverse(); + editedLine.forEach(line => { + startLine = line.range.start.line + before; + if (line.text == "\n") { + newEditedLine.push(line); + } else { + line.text.split(/\n/).forEach(text => { + newEditedLine.push(generateTextDocumentContentChange(startLine, line.text)); + startLine++; + before++; + }) + before--; + } + }); + return newEditedLine.reverse(); +} + +function handleLineDiff(editedLine: TextDocumentContentChangeEvent[], context, diffLine: number) { + let positions = mapToArray(context.deco).map(_ => Object({oldPosition: _, newPosition: _})); - timeout = setTimeout(updateDecorations, 500); + if (diffLine < 0) { + editedLine = handleLineRemoved(editedLine, positions); + } else { + editedLine = handleLineAdded(editedLine, positions); } + positions = positions.filter(position => { + if (position.newPosition === null) { + context.deco.get(position.oldPosition).forEach(decoration => decoration.dispose()) + return false; + } + return true + }); + let newDeco = new Map(); + positions.forEach(position => { + if (newDeco.has(position.newPosition)) { + newDeco.set(position.newPosition, newDeco.get(position.newPosition).concat(context.deco.get(position.oldPosition))); + } else { + newDeco.set(position.newPosition, context.deco.get(position.oldPosition)); + } + }); + context.deco = newDeco; + return editedLine; +} - function updateDecorations( /*editor: TextEditor, editedRange: Range*/ ) { - if (!editor) { +function handleLineAdded(editedLine: TextDocumentContentChangeEvent[], position) { + editedLine = mutEditedLIne(editedLine); + editedLine.forEach((line) => { + position.forEach(position => { + if(position.oldPosition > line.range.start.line) { + position.newPosition = position.newPosition + 1; + } + }); + }); + return editedLine +} + +function updatePositionsForDeletion(range, positions) { + let rangeLength = range.end.line - range.start.line; + positions.forEach(position => { + if (position.newPosition === null) { + return; + } + if(position.oldPosition >= range.start.line && position.oldPosition < (range.end.line + 1)) { + position.newPosition = null; return; } + if (position.oldPosition >= range.end.line) { + position.newPosition = position.newPosition - rangeLength; + } + if (position.newPosition < 0) { + position.newPosition = 0; + } + }); + return positions; +} +function handleLineRemoved(editedLine: TextDocumentContentChangeEvent[], positions) { + editedLine.reverse(); + editedLine.forEach((line) => { + positions = updatePositionsForDeletion(line.range, positions); + }); + editedLine.reverse(); + + return mutEditedLIneForDeletion(editedLine); +} +function updateDecorations(editedLine: TextDocumentContentChangeEvent[], context, cb:Function) { + let diffLine = context.current_editor.document.lineCount - context.nbLine; + + if (diffLine !== 0) { + editedLine = handleLineDiff(editedLine, context, diffLine); + context.nbLine = context.current_editor.document.lineCount; + } + checkDecorationForUpdate(editedLine, context, cb); +} - let disposed = decorations.filter(decoration => { - decoration.checkDecoration(editor); - return decoration.disposed; - }); +function checkDecorationForUpdate(editedLine: TextDocumentContentChangeEvent[], context, cb: Function) { + editedLine.forEach((line:TextDocumentContentChangeEvent) => { + if (context.deco.has(line.range.start.line)) { + context.deco.get(line.range.start.line).forEach(decoration => { + decoration.dispose(); + }); + } + context.deco.set(line.range.start.line, []); + + let colors = ColorUtil.extractColor(context.current_editor.document.lineAt(line.range.start.line).text); + let decorations: ColorDecoration[] = []; + colors.forEach((color) => { + let startPos = new Position(line.range.start.line, color.positionInText); + let endPos = new Position(line.range.start.line, color.positionInText + color.value.length); - let text = window.activeTextEditor.document.getText(); - let match = null; - let start = 0; - while (match = HEXA_COLOR.exec(text)) { - let startPos = editor.document.positionAt(start + match.index); - let endPos = editor.document.positionAt(start + match.index + match[1].length); - start += match.index + match[1].length; - text = text.substr(match.index + match[1].length); - // let alreadyIn = decorations.find(decoration => decoration.textPosition.start.isEqual(startPos) && decoration.textPosition.end.isEqual(endPos)); - // console.log(alreadyIn); - // if (alreadyIn) { - // continue; - // } let range = new Range(startPos, endPos); + let decoration = new ColorDecoration(range, color); + if (context.deco.has(startPos.line)) { + context.deco.set(startPos.line, context.deco.get(startPos.line).concat([decoration])); + } else { + context.deco.set(startPos.line, [decoration]); + } + context.current_editor.setDecorations(decoration.decoration, [range]); + }); + }); + cb(); +} - let decoration = generateDecorator(match[1]); - decorations.push(new ColorDecoration(range, decoration, HEXA_COLOR, match[1])); - editor.setDecorations(decoration, [range]); +function initDecorations(context, cb:Function) { + if (!context.current_editor) { + return; + } + context.nbLine = context.current_editor.document.lineCount; + + let text = context.current_editor.document.getText(); //should read line by line instead + let colors = ColorUtil.extractColor(text); + let decorations = generateDecorations(colors, context); + updateEditorDecorationFromMap(context.deco, context.current_editor); + cb(); +} + +function generateDecorations(colors: Color[], context): ColorDecoration[] { + let decorations: ColorDecoration[] = []; + colors.forEach((color) => { + let startPos = context.current_editor.document.positionAt(color.positionInText); + let endPos = context.current_editor.document.positionAt(color.positionInText + color.value.length); + let range = new Range(startPos, endPos); + if (context.deco.has(startPos.line)) { + context.deco.set(startPos.line, context.deco.get(startPos.line).concat([new ColorDecoration(range, color)])); + } else { + context.deco.set(startPos.line, [new ColorDecoration(range, color)]); + } + }); + return decorations; +} +function updateEditorDecorationFromMap(decorations: Map < number, ColorDecoration[] >, editor: TextEditor ) { + let it = decorations.entries(); + let tmp = it.next(); + while(!tmp.done) { + tmp.value[1].forEach(decoration => editor.setDecorations(decoration.decoration, [decoration.textPosition])) + tmp= it.next(); } +} + +export function activate(context: ExtensionContext) { + let decorations : Map < string, Map < number, ColorDecoration[] > > = new Map(); + let extension = { + current_editor: null, + nbLine: 0, + deco: null } + let q = new Queue(); + let editor = window.activeTextEditor; if (editor) { - triggerUpdateDecorations(); + extension.current_editor = editor, + extension.deco = new Map(); + decorations.set(editor.document.fileName, extension.deco); + q.push((cb)=> initDecorations(extension, cb)) } window.onDidChangeActiveTextEditor(newEditor => { - editor = newEditor; - if (editor) { - triggerUpdateDecorations(); + extension.current_editor = newEditor + if (newEditor && !decorations.has(newEditor.document.fileName)) { + extension.deco = new Map(); + } else { + extension.deco = decorations.get(newEditor.document.fileName); } + return q.push((cb)=> initDecorations(extension, cb)) + }, null, context.subscriptions); - workspace.onDidChangeTextDocument(event => { + workspace.onDidChangeTextDocument((event: TextDocumentChangeEvent) => { if (editor && event.document === editor.document) { - triggerUpdateDecorations( /*event.contentChanges*/ ); + q.push((cb)=> updateDecorations(event.contentChanges, extension, cb)) } }, null, context.subscriptions); } - -function generateDecorator(color: string): TextEditorDecorationType { - let textColor = null; - let luminance = ColorUtil.luminance(color); - if (luminance < 0.7) { - textColor = '#fff'; - } else { - textColor = '#000'; - } - let backgroundDecorationType = window.createTextEditorDecorationType({ - borderWidth: "1px", - borderStyle: "solid", - borderColor: color, - backgroundColor: color, - color: textColor - }); - return backgroundDecorationType; -} - // this method is called when your extension is deactivated export function deactivate() {} - - -class ColorDecoration { - public textPosition: Range; - private _decoration: TextEditorDecorationType; - private _matcher: RegExp; - private _match: string; - public disposed: boolean = false; - - public constructor(textPosition: Range, decoration: TextEditorDecorationType, matcher: RegExp, match: string) { - this.textPosition = textPosition; - this._decoration = decoration; - this._matcher = matcher; - this._match = match; - } - public checkDecoration(editor: TextEditor): void { - let character_after = editor.document.lineAt(this.textPosition.start.line).text.substring(this.textPosition.end.character, this.textPosition.end.character + 1); - let text = editor.document.lineAt(this.textPosition.start.line).text.substring(this.textPosition.start.character, this.textPosition.end.character + 1); - - if (!text.match(this._matcher)) { - this._decoration.dispose(); - this.disposed = true; - return; - } - if (text === this._match && character_after !== "") { - return; - } - this._match = text; - this._updateDecoration(editor); - return; - } - - private _updateDecoration(editor) { - this._decoration.dispose(); - let decoration = generateDecorator(this._match); - this._decoration = decoration; - editor.setDecorations(this._decoration, [{ - range: this.textPosition - }]); - } - public dispose(): void { - this._decoration.dispose(); - } -} diff --git a/src/queue.ts b/src/queue.ts new file mode 100644 index 00000000..96914035 --- /dev/null +++ b/src/queue.ts @@ -0,0 +1,33 @@ + +class Queue { + + private _running = false; + + private _queue: Function[] = []; + + public push(f:Function) { + + var _this = this; + this._queue.push(f); + + if(!this._running) { + // if nothing is running, then start the engines! + this._next(); + } + + return this; // for chaining fun! + } + private _next() { + this._running = false; + //get the first element off the queue + var shift = this._queue.shift(); + if(shift) { + this._running = true; + shift(()=> { + this._next(); + }); + } + } +} + +export default Queue; diff --git a/test/color-regex.test.ts b/test/color-regex.test.ts new file mode 100644 index 00000000..c60c60c1 --- /dev/null +++ b/test/color-regex.test.ts @@ -0,0 +1,56 @@ +import { assert } from 'chai'; + +import { HEXA_COLOR } from '../src/color-regex'; + +// Defines a Mocha test suite to group tests of similar kind together +describe("Test CSS hexa shorthand color Regex", () => { + it('Should match color with only integer', function () { + assert.ok('#000'.match(HEXA_COLOR)); + }); + it('Should match color with letters and integers', function () { + assert.ok('#f0a'.match(HEXA_COLOR)); + }); + it('Should match color with only letters', function () { + assert.ok('#fff'.match(HEXA_COLOR)); + }); + it('Regex should not care about the case', function () { + assert.ok('#Abc'.match(HEXA_COLOR)); + }); + it('Should match with different characters at the end', function () { + assert.ok('#Abc'.match(HEXA_COLOR)); + assert.ok('#Abc '.match(HEXA_COLOR)); + assert.ok('#Abc,'.match(HEXA_COLOR)); + assert.ok('#Abc;'.match(HEXA_COLOR)); + assert.ok('#Abc\n'.match(HEXA_COLOR)); + }); + it('Should not match', function () { + assert.notOk('#AbG'.match(HEXA_COLOR)); + assert.notOk('#AbcG'.match(HEXA_COLOR)); + assert.notOk('#Ab'.match(HEXA_COLOR)); + }); +}); +describe("Test CSS hexa color Regex", () => { + it('Should match color with only integer', function () { + assert.ok('#000000'.match(HEXA_COLOR)); + }); + it('Should match color with letters and integers', function () { + assert.ok('#f0f0f0'.match(HEXA_COLOR)); + }); + it('Should match color with only letters', function () { + assert.ok('#ffffff'.match(HEXA_COLOR)); + }); + it('Regex should not care about the case', function () { + assert.ok('#Abc012'.match(HEXA_COLOR)); + }); + it('Should match with different characters at the end', function () { + assert.ok('#ffffff '.match(HEXA_COLOR)); + assert.ok('#ffffff,'.match(HEXA_COLOR)); + assert.ok('#ffffff;'.match(HEXA_COLOR)); + assert.ok('#ffffff\n'.match(HEXA_COLOR)); + }); + it('Should not match', function () { + assert.notOk('#fffffg'.match(HEXA_COLOR)); + assert.notOk('#ffffffg'.match(HEXA_COLOR)); + assert.notOk('#fffff'.match(HEXA_COLOR)); + }); +}); diff --git a/test/color-util.test.ts b/test/color-util.test.ts new file mode 100644 index 00000000..a1a0874b --- /dev/null +++ b/test/color-util.test.ts @@ -0,0 +1,20 @@ +import { assert } from 'chai'; + +import ColorUtil from '../src/color-util'; +import Color from '../src/color'; + +describe('Test utility fonction', () => { + it('Should return the rgb value of a color', () => { + assert.deepEqual(ColorUtil.getRGB(new Color('hexa','#fff')), [255, 255, 255], 'Should return rgb values for CSS hexa shorthand color'); + assert.deepEqual(ColorUtil.getRGB(new Color('hexa','#ffffff')), [255, 255, 255], 'Should return rgb values for CSS hexa color'); + }); + it('Should return the color luminance', () => { + assert.equal(ColorUtil.luminance(new Color('hexa','#fff')), 1, 'Should be "1" for #fff'); + assert.equal(ColorUtil.luminance(new Color('hexa','#ffffff')), 1, 'Should be "1" for #ffffff'); + assert.equal(ColorUtil.luminance(new Color('hexa','#000')), 0, 'Should be "0" for #000'); + assert.equal(ColorUtil.luminance(new Color('hexa','#000000')), 0, 'Should be "0" for #000000'); + + assert.equal(ColorUtil.luminance(new Color('hexa','#ccc')).toFixed(1), 0.6, 'Should be around "0.6" for #ccc'); + + }); +}); diff --git a/test/extension.test.ts b/test/extension.test.ts index 05ad6b6f..8497db58 100644 --- a/test/extension.test.ts +++ b/test/extension.test.ts @@ -1,126 +1,36 @@ -import { assert } from 'chai'; +import { + assert +} from 'chai'; -// You can import and use all API from the 'vscode' module -// as well as import your extension to test it -import { HEXA_COLOR } from '../src/color-regex'; -import ColorUtil from '../src/color-util'; +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +import * as vscode from 'vscode'; +import * as colorize from '../src/extension'; +import * as path from 'path'; -// Defines a Mocha test suite to group tests of similar kind together -describe("Test CSS hexa shorthand color Regex", () => { - it('Should match color with only integer', function () { - assert.ok('#000'.match(HEXA_COLOR)); - }); - it('Should match color with letters and integers', function () { - assert.ok('#f0a'.match(HEXA_COLOR)); - }); - it('Should match color with only letters', function () { - assert.ok('#fff'.match(HEXA_COLOR)); - }); - it('Regex should not care about the case', function () { - assert.ok('#Abc'.match(HEXA_COLOR)); - }); - it('Should match with different characters at the end', function () { - assert.ok('#Abc'.match(HEXA_COLOR)); - assert.ok('#Abc '.match(HEXA_COLOR)); - assert.ok('#Abc,'.match(HEXA_COLOR)); - assert.ok('#Abc;'.match(HEXA_COLOR)); - assert.ok('#Abc\n'.match(HEXA_COLOR)); - }); - it('Should not match', function () { - assert.notOk('#AbG'.match(HEXA_COLOR)); - assert.notOk('#AbcG'.match(HEXA_COLOR)); - assert.notOk('#Ab'.match(HEXA_COLOR)); - }); -}); -describe("Test CSS hexa color Regex", () => { - it('Should match color with only integer', function () { - assert.ok('#000000'.match(HEXA_COLOR)); - }); - it('Should match color with letters and integers', function () { - assert.ok('#f0f0f0'.match(HEXA_COLOR)); - }); - it('Should match color with only letters', function () { - assert.ok('#ffffff'.match(HEXA_COLOR)); - }); - it('Regex should not care about the case', function () { - assert.ok('#Abc012'.match(HEXA_COLOR)); - }); - it('Should match with different characters at the end', function () { - assert.ok('#ffffff '.match(HEXA_COLOR)); - assert.ok('#ffffff,'.match(HEXA_COLOR)); - assert.ok('#ffffff;'.match(HEXA_COLOR)); - assert.ok('#ffffff\n'.match(HEXA_COLOR)); - }); - it('Should not match', function () { - assert.notOk('#fffffg'.match(HEXA_COLOR)); - assert.notOk('#ffffffg'.match(HEXA_COLOR)); - assert.notOk('#fffff'.match(HEXA_COLOR)); - }); -}); -describe("Test CSS hexa shorthand color Regex", () => { - it('Should match color with only integer', function () { - assert.ok('#000'.match(HEXA_COLOR)); - }); - it('Should match color with letters and integers', function () { - assert.ok('#f0a'.match(HEXA_COLOR)); - }); - it('Should match color with only letters', function () { - assert.ok('#fff'.match(HEXA_COLOR)); - }); - it('Regex should not care about the case', function () { - assert.ok('#Abc'.match(HEXA_COLOR)); - }); - it('Should match with different characters at the end', function () { - assert.ok('#Abc'.match(HEXA_COLOR)); - assert.ok('#Abc '.match(HEXA_COLOR)); - assert.ok('#Abc,'.match(HEXA_COLOR)); - assert.ok('#Abc;'.match(HEXA_COLOR)); - assert.ok('#Abc\n'.match(HEXA_COLOR)); - }); - it('Should not match', function () { - assert.notOk('#AbG'.match(HEXA_COLOR)); - assert.notOk('#AbcG'.match(HEXA_COLOR)); - assert.notOk('#Ab'.match(HEXA_COLOR)); - }); -}); -describe("Test CSS hexa color Regex", () => { - it('Should match color with only integer', () => { - assert.ok('#000000'.match(HEXA_COLOR)); - }); - it('Should match color with letters and integers', () => { - assert.ok('#f0f0f0'.match(HEXA_COLOR)); - }); - it('Should match color with only letters', () => { - assert.ok('#ffffff'.match(HEXA_COLOR)); - }); - it('Regex should not care about the case', () => { - assert.ok('#Abc012'.match(HEXA_COLOR)); - }); - it('Should match with different characters at the end', () => { - assert.ok('#ffffff '.match(HEXA_COLOR)); - assert.ok('#ffffff,'.match(HEXA_COLOR)); - assert.ok('#ffffff;'.match(HEXA_COLOR)); - assert.ok('#ffffff\n'.match(HEXA_COLOR)); - }); - it('Should not match', () => { - assert.notOk('#fffffg'.match(HEXA_COLOR)); - assert.notOk('#ffffffg'.match(HEXA_COLOR)); - assert.notOk('#fffff'.match(HEXA_COLOR)); - }); -}); - -describe('Test utility fonction', () => { - it('Should return the rgb value of a color', () => { - assert.deepEqual(ColorUtil.getRGB('#fff'), [255, 255, 255], 'Should return rgb values for CSS hexa shorthand color'); - assert.deepEqual(ColorUtil.getRGB('#ffffff'), [255, 255, 255], 'Should return rgb values for CSS hexa color'); - }); - it('Should return the color luminance', () => { - assert.equal(ColorUtil.luminance('#fff'), 1, 'Should be "1" for #fff'); - assert.equal(ColorUtil.luminance('#ffffff'), 1, 'Should be "1" for #ffffff'); - assert.equal(ColorUtil.luminance('#000'), 0, 'Should be "0" for #000'); - assert.equal(ColorUtil.luminance('#000000'), 0, 'Should be "0" for #000000'); - - assert.equal(ColorUtil.luminance('#ccc').toFixed(1), 0.6, 'Should be around "0.6" for #ccc'); +const isWin = /^win/.test(process.platform); +const ext = vscode.extensions.getExtension("kamikillerto.vscode-colorize"); +let fixtureSourcePath = path.join(__dirname, '..', '..', 'fixtures'); - }); +describe("Extension", () => { + it("is not activated initially", () => { + assert.equal(ext.isActive, false); + }); + // it("is activated successfully upon opening a css file", done => { + // vscode.workspace.openTextDocument(`${fixtureSourcePath}/styles.sass`) + // .then(() => { + // assert.equal(ext.isActive, true); + // }) + // .then(() => done(), e => done(new Error(e))); + // }); }); + +// describe("Activated extension", () => { +// before(done => { +// vscode.workspace.openTextDocument(`${sampleFileUri}.css`) +// .then(() => done(), e => done(new Error(e))); +// }); +// // it("", done => { +// // extension. +// // }); +// }); diff --git a/test/index.ts b/test/index.ts index 1403e866..e1b035e7 100644 --- a/test/index.ts +++ b/test/index.ts @@ -15,7 +15,7 @@ let testRunner = require('vscode/lib/testrunner'); // You can directly control Mocha options by uncommenting the following lines // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info testRunner.configure({ - // ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) + ui: 'bdd', useColors: true // colored output from test results });