Skip to content

Commit

Permalink
test: color preview integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
abose committed Dec 9, 2024
1 parent 9f33d14 commit dbaf5fb
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 4 deletions.
13 changes: 13 additions & 0 deletions docs/API-Reference/editor/Editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const Editor = brackets.getModule("editor/Editor")
* [.setGutterMarker(lineNumber, gutterName, marker)](#Editor+setGutterMarker)
* [.getGutterMarker(lineNumber, gutterName)](#Editor+getGutterMarker)
* [.clearGutterMarker(lineNumber, gutterName)](#Editor+clearGutterMarker)
* [.isGutterActive(gutterName)](#Editor+isGutterActive)
* [.clearGutter(gutterName)](#Editor+clearGutter)
* _static_
* [.getMarkOptionUnderlineError](#Editor.getMarkOptionUnderlineError)
Expand Down Expand Up @@ -1270,6 +1271,18 @@ on the line.
| lineNumber | <code>number</code> | The line number for the inserted gutter marker |
| gutterName | <code>string</code> | The name of the gutter |

<a name="Editor+isGutterActive"></a>

### editor.isGutterActive(gutterName)
Returns true if this editor has the named gutter activated. gutters are considered active if the gutter is
registered for the language of the file currently shown in the editor.

**Kind**: instance method of [<code>Editor</code>](#Editor)

| Param | Type | Description |
| --- | --- | --- |
| gutterName | <code>string</code> | The name of the gutter to check |

<a name="Editor+clearGutter"></a>

### editor.clearGutter(gutterName)
Expand Down
55 changes: 55 additions & 0 deletions src/extensions/default/DebugCommands/MacroRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ define(function (require, exports, module) {
EditorManager = brackets.getModule("editor/EditorManager"),
KeyEvent = brackets.getModule("utils/KeyEvent"),
Commands = brackets.getModule("command/Commands"),
FileSystem = brackets.getModule("filesystem/FileSystem"),
FileUtils = brackets.getModule("file/FileUtils"),
PreferencesManager = brackets.getModule("preferences/PreferencesManager"),
Editor = brackets.getModule("editor/Editor"),
Dialogs = brackets.getModule("widgets/Dialogs"),
Expand All @@ -68,6 +70,58 @@ define(function (require, exports, module) {
return jsPromise(FileViewController.openFileAndAddToWorkingSet(projectFilePath));
}

/**
* Reads a text file and returns a promise that resolves to the text
* @param filePath - project relative or full path
* @param {boolean?} bypassCache - an optional argument, if specified will read from disc instead of using cache.
* @returns {Promise<String>}
*/
function readTextFile(filePath, bypassCache) {
if(!filePath.startsWith('/')) {
filePath = path.join(ProjectManager.getProjectRoot().fullPath, filePath);
}
const file = FileSystem.getFileForPath(filePath);
return jsPromise(FileUtils.readAsText(file, bypassCache));
}

/**
* Asynchronously writes a file as UTF-8 encoded text.
* @param filePath - project relative or full path
* @param {String} text
* @param {boolean} allowBlindWrite Indicates whether or not CONTENTS_MODIFIED
* errors---which can be triggered if the actual file contents differ from
* the FileSystem's last-known contents---should be ignored.
* @return {Promise<null>} promise that will be resolved when
* file writing completes, or rejected with a FileSystemError string constant.
*/
function writeTextFile(filePath, text, allowBlindWrite) {
if(!filePath.startsWith('/')) {
filePath = path.join(ProjectManager.getProjectRoot().fullPath, filePath);
}
const file = FileSystem.getFileForPath(filePath);
return jsPromise(FileUtils.writeText(file, text, allowBlindWrite));
}

/**
* deletes a file or dir at given path
* @param filePath - project relative or full path
* @return {Promise<null>} promise that will be resolved when path removed
*/
function deletePath(filePath) {
if(!filePath.startsWith('/')) {
filePath = path.join(ProjectManager.getProjectRoot().fullPath, filePath);
}
return new Promise((resolve, reject) => {
window.fs.unlink(filePath, (err)=>{
if (err) {
reject(err);
return;
}
resolve();
});
});
}


/**
* Set cursor positions or text selections in the active CodeMirror editor based on a specified format.
Expand Down Expand Up @@ -616,6 +670,7 @@ define(function (require, exports, module) {
}

const __PR= {
readTextFile, writeTextFile, deletePath,
openFile, setCursors, expectCursorsToBe, keydown, typeAtCursor, validateText, validateAllMarks, validateMarks,
closeFile, closeAll, undo, redo, setPreference, getPreference, validateEqual, validateNotEqual, execCommand,
awaitsFor, waitForModalDialog, waitForModalDialogClosed, clickDialogButtonID, clickDialogButton,
Expand Down
11 changes: 7 additions & 4 deletions src/extensionsIntegrated/CSSColorPreview/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,16 @@ define(function (require, exports, module) {
// Extension variables.
const COLOR_REGEX = ColorUtils.COLOR_REGEX, // used to match color
GUTTER_NAME = "CodeMirror-colorGutter",
DUMMY_GUTTER_CLASS = "CodeMirror-colorGutter-none",
SINGLE_COLOR_PREVIEW_CLASS = "ico-cssColorPreview",
MULTI_COLOR_PREVIEW_CLASS = "ico-multiple-cssColorPreview",
COLOR_PREVIEW_GUTTER_PRIORITY = 200,
COLOR_LANGUAGES= ["css", "scss", "less", "sass", "stylus", "html", "svg", "jsx", "tsx",
"php", "ejs", "erb_html", "pug"];


// For preferences settings, to toggle this feature on/off
const PREFERENCES_CSS_COLOR_PREVIEW = "CSSColorPreview";
const PREFERENCES_CSS_COLOR_PREVIEW = "colorPreview";
let enabled = true; // by default:- on

PreferencesManager.definePreference(PREFERENCES_CSS_COLOR_PREVIEW, "boolean", enabled, {
Expand Down Expand Up @@ -138,7 +141,7 @@ define(function (require, exports, module) {
if (obj.colorValues.length === 1) {
// Single color preview
$marker = $("<i>")
.addClass("ico-cssColorPreview")
.addClass(SINGLE_COLOR_PREVIEW_CLASS)
.css('background-color', obj.colorValues[0]);

editor.setGutterMarker(obj.lineNumber, GUTTER_NAME, $marker[0]);
Expand All @@ -149,7 +152,7 @@ define(function (require, exports, module) {
});
} else {
// Multiple colors preview
$marker = $("<div>").addClass("ico-multiple-cssColorPreview");
$marker = $("<div>").addClass(MULTI_COLOR_PREVIEW_CLASS);

// Positions for up to 4 colors in grid
const positions = [
Expand Down Expand Up @@ -188,7 +191,7 @@ define(function (require, exports, module) {
let marker = editor.getGutterMarker(line, GUTTER_NAME);
if(!marker){
let $marker = $('<div>')
.addClass(GUTTER_NAME);
.addClass(DUMMY_GUTTER_CLASS);
editor.setGutterMarker(line, GUTTER_NAME, $marker[0]);
}
}
Expand Down
1 change: 1 addition & 0 deletions test/UnitTestSuite.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ define(function (require, exports, module) {
require("spec/Extn-RecentProjects-integ-test");
require("spec/Extn-JSHint-integ-test");
require("spec/Extn-ESLint-integ-test");
require("spec/Extn-CSSColorPreview-integ-test");
// extension integration tests
require("spec/Extn-CSSCodeHints-integ-test");
require("spec/Extn-HTMLCodeHints-Lint-integ-test");
Expand Down
18 changes: 18 additions & 0 deletions test/spec/CSSColorPreview-test-files/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Example</title>
</head>
<body>
<h1 style="color: blue;">test color</h1>
<h1>test no color</h1>
<h1>test add color</h1>
<div style="color: #00ff8c;">green color</div>
<div style="color: #00ff8c red;">multiple colors 2</div>
<div style="color: #b7ff00 green #3e4395;">multiple colors 3</div>
<div style="color: #ff0090 #802095 #954e3e #454e3e;">multiple colors 4</div>
<div style="color: #ff0090 #802095 #954e3e #454e3e #150e3e;">multiple colors 5</div>
</body>
</html>
104 changes: 104 additions & 0 deletions test/spec/Extn-CSSColorPreview-integ-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* GNU AGPL-3.0 License
*
* Copyright (c) 2021 - present core.ai . All rights reserved.
* Original work Copyright (c) 2013 - 2021 Adobe Systems Incorporated. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
* for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
*
*/

/*global describe, it, expect, beforeAll, afterAll, beforeEach, awaitsForDone, awaits, awaitsFor, path, jsPromise */

define(function (require, exports, module) {


var SpecRunnerUtils = require("spec/SpecRunnerUtils");

describe("integration:ColorPreview in gutter", function () {
const testRootSpec = "/spec/CSSColorPreview-test-files/";
const GUTTER_NAME = "CodeMirror-colorGutter",
SINGLE_COLOR_PREVIEW_CLASS = "ico-cssColorPreview",
MULTI_COLOR_PREVIEW_CLASS = "ico-multiple-cssColorPreview",
DUMMY_GUTTER_CLASS = "CodeMirror-colorGutter-none";
let testProjectFolder,
testWindow,
EditorManager,
__PR; // __PR can be debugged using debug menu> phoenix code diag tools> test builder

beforeAll(async function () {
testWindow = await SpecRunnerUtils.createTestWindowAndRun();
// Load module instances from brackets.test
testProjectFolder = await SpecRunnerUtils.getTempTestDirectory(testRootSpec);
await SpecRunnerUtils.loadProjectInTestWindow(testProjectFolder);
__PR = testWindow.__PR;
EditorManager = testWindow.EditorManager;
}, 30000);

afterAll(async function () {
await __PR.closeAll();
testWindow = null;
__PR = null;
EditorManager = null;
await SpecRunnerUtils.closeTestWindow();
}, 30000);

it("should color gutter not appear in cpp files", async function () {
const fileName = "a.cpp";
await __PR.writeTextFile(fileName, "#include <iostream>", true);
await __PR.openFile(fileName);
const editor = EditorManager.getActiveEditor();
__PR.validateEqual(editor.isGutterActive(GUTTER_NAME), false);
await __PR.closeFile();
});

function testHTMLFile(fileName) {
it(`should color gutter appear as expected ${fileName}`, async function () {
const htmlText = await __PR.readTextFile("base.html");
await __PR.writeTextFile(fileName, htmlText, true);
await __PR.openFile(fileName);
const editor = EditorManager.getActiveEditor();
__PR.validateEqual(editor.isGutterActive(GUTTER_NAME), true);

// the line with cursor if there is no color should have a dummy color gutter
__PR.setCursors(["1:1"]);
let gutterMarker = editor.getGutterMarker(0, GUTTER_NAME);
__PR.validateEqual(gutterMarker.classList.contains(DUMMY_GUTTER_CLASS), true);

// should have no color boxes as expected
const colorBoxesInLines = [8, 11, 12, 13, 14, 15];
const singleColorBoxesInLines = [8, 11];
const multiColorBoxesInLines = [12, 13, 14, 15];
for (let line = 1; line < editor.lineCount(); line++) {
gutterMarker = editor.getGutterMarker(line, GUTTER_NAME);
if (!colorBoxesInLines.includes(line)) {
// there should be no color box here
__PR.validateEqual(!!gutterMarker, false);
} else if(singleColorBoxesInLines.includes(line)) {
__PR.validateEqual(gutterMarker.classList.contains(SINGLE_COLOR_PREVIEW_CLASS), true);
} else if(multiColorBoxesInLines.includes(line)) {
__PR.validateEqual(gutterMarker.classList.contains(MULTI_COLOR_PREVIEW_CLASS), true);
}
}
await __PR.closeFile();

});
}

const htmlFiles = ["a.html", "a.htm", "a.xhtml", "a.php", "a.jsp"];
for(let htmlFile of htmlFiles){
testHTMLFile(htmlFile);
}
});
});

0 comments on commit dbaf5fb

Please sign in to comment.