Skip to content

Commit dbaf5fb

Browse files
committed
test: color preview integration tests
1 parent 9f33d14 commit dbaf5fb

File tree

6 files changed

+198
-4
lines changed

6 files changed

+198
-4
lines changed

docs/API-Reference/editor/Editor.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ const Editor = brackets.getModule("editor/Editor")
110110
* [.setGutterMarker(lineNumber, gutterName, marker)](#Editor+setGutterMarker)
111111
* [.getGutterMarker(lineNumber, gutterName)](#Editor+getGutterMarker)
112112
* [.clearGutterMarker(lineNumber, gutterName)](#Editor+clearGutterMarker)
113+
* [.isGutterActive(gutterName)](#Editor+isGutterActive)
113114
* [.clearGutter(gutterName)](#Editor+clearGutter)
114115
* _static_
115116
* [.getMarkOptionUnderlineError](#Editor.getMarkOptionUnderlineError)
@@ -1270,6 +1271,18 @@ on the line.
12701271
| lineNumber | <code>number</code> | The line number for the inserted gutter marker |
12711272
| gutterName | <code>string</code> | The name of the gutter |
12721273

1274+
<a name="Editor+isGutterActive"></a>
1275+
1276+
### editor.isGutterActive(gutterName)
1277+
Returns true if this editor has the named gutter activated. gutters are considered active if the gutter is
1278+
registered for the language of the file currently shown in the editor.
1279+
1280+
**Kind**: instance method of [<code>Editor</code>](#Editor)
1281+
1282+
| Param | Type | Description |
1283+
| --- | --- | --- |
1284+
| gutterName | <code>string</code> | The name of the gutter to check |
1285+
12731286
<a name="Editor+clearGutter"></a>
12741287

12751288
### editor.clearGutter(gutterName)

src/extensions/default/DebugCommands/MacroRunner.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ define(function (require, exports, module) {
4949
EditorManager = brackets.getModule("editor/EditorManager"),
5050
KeyEvent = brackets.getModule("utils/KeyEvent"),
5151
Commands = brackets.getModule("command/Commands"),
52+
FileSystem = brackets.getModule("filesystem/FileSystem"),
53+
FileUtils = brackets.getModule("file/FileUtils"),
5254
PreferencesManager = brackets.getModule("preferences/PreferencesManager"),
5355
Editor = brackets.getModule("editor/Editor"),
5456
Dialogs = brackets.getModule("widgets/Dialogs"),
@@ -68,6 +70,58 @@ define(function (require, exports, module) {
6870
return jsPromise(FileViewController.openFileAndAddToWorkingSet(projectFilePath));
6971
}
7072

73+
/**
74+
* Reads a text file and returns a promise that resolves to the text
75+
* @param filePath - project relative or full path
76+
* @param {boolean?} bypassCache - an optional argument, if specified will read from disc instead of using cache.
77+
* @returns {Promise<String>}
78+
*/
79+
function readTextFile(filePath, bypassCache) {
80+
if(!filePath.startsWith('/')) {
81+
filePath = path.join(ProjectManager.getProjectRoot().fullPath, filePath);
82+
}
83+
const file = FileSystem.getFileForPath(filePath);
84+
return jsPromise(FileUtils.readAsText(file, bypassCache));
85+
}
86+
87+
/**
88+
* Asynchronously writes a file as UTF-8 encoded text.
89+
* @param filePath - project relative or full path
90+
* @param {String} text
91+
* @param {boolean} allowBlindWrite Indicates whether or not CONTENTS_MODIFIED
92+
* errors---which can be triggered if the actual file contents differ from
93+
* the FileSystem's last-known contents---should be ignored.
94+
* @return {Promise<null>} promise that will be resolved when
95+
* file writing completes, or rejected with a FileSystemError string constant.
96+
*/
97+
function writeTextFile(filePath, text, allowBlindWrite) {
98+
if(!filePath.startsWith('/')) {
99+
filePath = path.join(ProjectManager.getProjectRoot().fullPath, filePath);
100+
}
101+
const file = FileSystem.getFileForPath(filePath);
102+
return jsPromise(FileUtils.writeText(file, text, allowBlindWrite));
103+
}
104+
105+
/**
106+
* deletes a file or dir at given path
107+
* @param filePath - project relative or full path
108+
* @return {Promise<null>} promise that will be resolved when path removed
109+
*/
110+
function deletePath(filePath) {
111+
if(!filePath.startsWith('/')) {
112+
filePath = path.join(ProjectManager.getProjectRoot().fullPath, filePath);
113+
}
114+
return new Promise((resolve, reject) => {
115+
window.fs.unlink(filePath, (err)=>{
116+
if (err) {
117+
reject(err);
118+
return;
119+
}
120+
resolve();
121+
});
122+
});
123+
}
124+
71125

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

618672
const __PR= {
673+
readTextFile, writeTextFile, deletePath,
619674
openFile, setCursors, expectCursorsToBe, keydown, typeAtCursor, validateText, validateAllMarks, validateMarks,
620675
closeFile, closeAll, undo, redo, setPreference, getPreference, validateEqual, validateNotEqual, execCommand,
621676
awaitsFor, waitForModalDialog, waitForModalDialogClosed, clickDialogButtonID, clickDialogButton,

src/extensionsIntegrated/CSSColorPreview/main.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ define(function (require, exports, module) {
4040
// Extension variables.
4141
const COLOR_REGEX = ColorUtils.COLOR_REGEX, // used to match color
4242
GUTTER_NAME = "CodeMirror-colorGutter",
43+
DUMMY_GUTTER_CLASS = "CodeMirror-colorGutter-none",
44+
SINGLE_COLOR_PREVIEW_CLASS = "ico-cssColorPreview",
45+
MULTI_COLOR_PREVIEW_CLASS = "ico-multiple-cssColorPreview",
4346
COLOR_PREVIEW_GUTTER_PRIORITY = 200,
4447
COLOR_LANGUAGES= ["css", "scss", "less", "sass", "stylus", "html", "svg", "jsx", "tsx",
4548
"php", "ejs", "erb_html", "pug"];
4649

4750

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

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

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

154157
// Positions for up to 4 colors in grid
155158
const positions = [
@@ -188,7 +191,7 @@ define(function (require, exports, module) {
188191
let marker = editor.getGutterMarker(line, GUTTER_NAME);
189192
if(!marker){
190193
let $marker = $('<div>')
191-
.addClass(GUTTER_NAME);
194+
.addClass(DUMMY_GUTTER_CLASS);
192195
editor.setGutterMarker(line, GUTTER_NAME, $marker[0]);
193196
}
194197
}

test/UnitTestSuite.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ define(function (require, exports, module) {
125125
require("spec/Extn-RecentProjects-integ-test");
126126
require("spec/Extn-JSHint-integ-test");
127127
require("spec/Extn-ESLint-integ-test");
128+
require("spec/Extn-CSSColorPreview-integ-test");
128129
// extension integration tests
129130
require("spec/Extn-CSSCodeHints-integ-test");
130131
require("spec/Extn-HTMLCodeHints-Lint-integ-test");
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Example</title>
7+
</head>
8+
<body>
9+
<h1 style="color: blue;">test color</h1>
10+
<h1>test no color</h1>
11+
<h1>test add color</h1>
12+
<div style="color: #00ff8c;">green color</div>
13+
<div style="color: #00ff8c red;">multiple colors 2</div>
14+
<div style="color: #b7ff00 green #3e4395;">multiple colors 3</div>
15+
<div style="color: #ff0090 #802095 #954e3e #454e3e;">multiple colors 4</div>
16+
<div style="color: #ff0090 #802095 #954e3e #454e3e #150e3e;">multiple colors 5</div>
17+
</body>
18+
</html>
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* GNU AGPL-3.0 License
3+
*
4+
* Copyright (c) 2021 - present core.ai . All rights reserved.
5+
* Original work Copyright (c) 2013 - 2021 Adobe Systems Incorporated. All rights reserved.
6+
*
7+
* This program is free software: you can redistribute it and/or modify it
8+
* under the terms of the GNU Affero General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
15+
* for more details.
16+
*
17+
* You should have received a copy of the GNU Affero General Public License
18+
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
19+
*
20+
*/
21+
22+
/*global describe, it, expect, beforeAll, afterAll, beforeEach, awaitsForDone, awaits, awaitsFor, path, jsPromise */
23+
24+
define(function (require, exports, module) {
25+
26+
27+
var SpecRunnerUtils = require("spec/SpecRunnerUtils");
28+
29+
describe("integration:ColorPreview in gutter", function () {
30+
const testRootSpec = "/spec/CSSColorPreview-test-files/";
31+
const GUTTER_NAME = "CodeMirror-colorGutter",
32+
SINGLE_COLOR_PREVIEW_CLASS = "ico-cssColorPreview",
33+
MULTI_COLOR_PREVIEW_CLASS = "ico-multiple-cssColorPreview",
34+
DUMMY_GUTTER_CLASS = "CodeMirror-colorGutter-none";
35+
let testProjectFolder,
36+
testWindow,
37+
EditorManager,
38+
__PR; // __PR can be debugged using debug menu> phoenix code diag tools> test builder
39+
40+
beforeAll(async function () {
41+
testWindow = await SpecRunnerUtils.createTestWindowAndRun();
42+
// Load module instances from brackets.test
43+
testProjectFolder = await SpecRunnerUtils.getTempTestDirectory(testRootSpec);
44+
await SpecRunnerUtils.loadProjectInTestWindow(testProjectFolder);
45+
__PR = testWindow.__PR;
46+
EditorManager = testWindow.EditorManager;
47+
}, 30000);
48+
49+
afterAll(async function () {
50+
await __PR.closeAll();
51+
testWindow = null;
52+
__PR = null;
53+
EditorManager = null;
54+
await SpecRunnerUtils.closeTestWindow();
55+
}, 30000);
56+
57+
it("should color gutter not appear in cpp files", async function () {
58+
const fileName = "a.cpp";
59+
await __PR.writeTextFile(fileName, "#include <iostream>", true);
60+
await __PR.openFile(fileName);
61+
const editor = EditorManager.getActiveEditor();
62+
__PR.validateEqual(editor.isGutterActive(GUTTER_NAME), false);
63+
await __PR.closeFile();
64+
});
65+
66+
function testHTMLFile(fileName) {
67+
it(`should color gutter appear as expected ${fileName}`, async function () {
68+
const htmlText = await __PR.readTextFile("base.html");
69+
await __PR.writeTextFile(fileName, htmlText, true);
70+
await __PR.openFile(fileName);
71+
const editor = EditorManager.getActiveEditor();
72+
__PR.validateEqual(editor.isGutterActive(GUTTER_NAME), true);
73+
74+
// the line with cursor if there is no color should have a dummy color gutter
75+
__PR.setCursors(["1:1"]);
76+
let gutterMarker = editor.getGutterMarker(0, GUTTER_NAME);
77+
__PR.validateEqual(gutterMarker.classList.contains(DUMMY_GUTTER_CLASS), true);
78+
79+
// should have no color boxes as expected
80+
const colorBoxesInLines = [8, 11, 12, 13, 14, 15];
81+
const singleColorBoxesInLines = [8, 11];
82+
const multiColorBoxesInLines = [12, 13, 14, 15];
83+
for (let line = 1; line < editor.lineCount(); line++) {
84+
gutterMarker = editor.getGutterMarker(line, GUTTER_NAME);
85+
if (!colorBoxesInLines.includes(line)) {
86+
// there should be no color box here
87+
__PR.validateEqual(!!gutterMarker, false);
88+
} else if(singleColorBoxesInLines.includes(line)) {
89+
__PR.validateEqual(gutterMarker.classList.contains(SINGLE_COLOR_PREVIEW_CLASS), true);
90+
} else if(multiColorBoxesInLines.includes(line)) {
91+
__PR.validateEqual(gutterMarker.classList.contains(MULTI_COLOR_PREVIEW_CLASS), true);
92+
}
93+
}
94+
await __PR.closeFile();
95+
96+
});
97+
}
98+
99+
const htmlFiles = ["a.html", "a.htm", "a.xhtml", "a.php", "a.jsp"];
100+
for(let htmlFile of htmlFiles){
101+
testHTMLFile(htmlFile);
102+
}
103+
});
104+
});

0 commit comments

Comments
 (0)