diff --git a/src/brackets.js b/src/brackets.js
index b88df63c2c5..3ef7d4d3771 100644
--- a/src/brackets.js
+++ b/src/brackets.js
@@ -151,42 +151,44 @@ define(function (require, exports, module) {
// in the modules since they would run in context of the unit test window,
// and would not have access to the app html/css.
brackets.test = {
- PreferencesManager : PreferencesManager,
- ProjectManager : ProjectManager,
+ CodeHintManager : CodeHintManager,
+ CodeInspection : CodeInspection,
+ CommandManager : CommandManager,
+ Commands : Commands,
+ CSSUtils : require("language/CSSUtils"),
+ DefaultDialogs : DefaultDialogs,
+ Dialogs : Dialogs,
DocumentCommandHandlers : DocumentCommandHandlers,
- FileViewController : FileViewController,
DocumentManager : DocumentManager,
+ DOMAgent : require("LiveDevelopment/Agents/DOMAgent"),
+ DragAndDrop : DragAndDrop,
EditorManager : EditorManager,
- Commands : Commands,
- WorkingSetView : WorkingSetView,
- PerfUtils : PerfUtils,
- JSUtils : JSUtils,
- CommandManager : CommandManager,
+ ExtensionLoader : ExtensionLoader,
+ ExtensionUtils : ExtensionUtils,
+ FileFilters : require("search/FileFilters"),
FileSyncManager : FileSyncManager,
FileSystem : FileSystem,
- Menus : Menus,
+ FileViewController : FileViewController,
+ FindInFiles : require("search/FindInFiles"),
+ HTMLInstrumentation : require("language/HTMLInstrumentation"),
+ Inspector : require("LiveDevelopment/Inspector/Inspector"),
+ InstallExtensionDialog : require("extensibility/InstallExtensionDialog"),
+ JSUtils : JSUtils,
KeyBindingManager : KeyBindingManager,
- CodeHintManager : CodeHintManager,
- Dialogs : Dialogs,
- DefaultDialogs : DefaultDialogs,
- DragAndDrop : DragAndDrop,
- CodeInspection : CodeInspection,
- CSSUtils : require("language/CSSUtils"),
+ LanguageManager : LanguageManager,
LiveDevelopment : require("LiveDevelopment/LiveDevelopment"),
LiveDevServerManager : require("LiveDevelopment/LiveDevServerManager"),
- DOMAgent : require("LiveDevelopment/Agents/DOMAgent"),
- Inspector : require("LiveDevelopment/Inspector/Inspector"),
+ Menus : Menus,
+ MultiRangeInlineEditor : require("editor/MultiRangeInlineEditor").MultiRangeInlineEditor,
NativeApp : NativeApp,
- ExtensionLoader : ExtensionLoader,
- ExtensionUtils : ExtensionUtils,
- UpdateNotification : require("utils/UpdateNotification"),
- InstallExtensionDialog : require("extensibility/InstallExtensionDialog"),
+ PerfUtils : PerfUtils,
+ PreferencesManager : PreferencesManager,
+ ProjectManager : ProjectManager,
RemoteAgent : require("LiveDevelopment/Agents/RemoteAgent"),
- HTMLInstrumentation : require("language/HTMLInstrumentation"),
- MultiRangeInlineEditor : require("editor/MultiRangeInlineEditor").MultiRangeInlineEditor,
- LanguageManager : LanguageManager,
- FindInFiles : require("search/FindInFiles"),
- FileFilters : require("search/FileFilters"),
+ ScrollTrackMarkers : require("search/ScrollTrackMarkers"),
+ UpdateNotification : require("utils/UpdateNotification"),
+ WorkingSetView : WorkingSetView,
+
doneLoading : false
};
diff --git a/src/search/FindInFiles.js b/src/search/FindInFiles.js
index a203ea792df..d4e62e8bfb4 100644
--- a/src/search/FindInFiles.js
+++ b/src/search/FindInFiles.js
@@ -1240,6 +1240,7 @@ define(function (require, exports, module) {
CommandManager.register(Strings.CMD_FIND_IN_FILES, Commands.EDIT_FIND_IN_FILES, _doFindInFiles);
CommandManager.register(Strings.CMD_FIND_IN_SUBTREE, Commands.EDIT_FIND_IN_SUBTREE, _doFindInSubtree);
- // For unit testing - updated in _doSearch() when search complete
+ // For unit testing
+ exports._doFindInFiles = _doFindInFiles;
exports._searchResults = null;
});
diff --git a/src/search/ScrollTrackMarkers.js b/src/search/ScrollTrackMarkers.js
index 283ee9a5b55..0325339a15b 100644
--- a/src/search/ScrollTrackMarkers.js
+++ b/src/search/ScrollTrackMarkers.js
@@ -158,9 +158,17 @@ define(function (require, exports, module) {
marks = marks.concat(posArray);
_renderMarks(posArray);
}
-
-
- exports.clear = clear;
- exports.setVisible = setVisible;
- exports.addTickmarks = addTickmarks;
+
+ // Private helper for unit tests
+ function _getTickmarks() {
+ return marks;
+ }
+
+
+ // For unit tests
+ exports._getTickmarks = _getTickmarks;
+
+ exports.clear = clear;
+ exports.setVisible = setVisible;
+ exports.addTickmarks = addTickmarks;
});
diff --git a/test/spec/FileFilters-test.js b/test/spec/FileFilters-test.js
index 19cb6003048..682e92e8624 100644
--- a/test/spec/FileFilters-test.js
+++ b/test/spec/FileFilters-test.js
@@ -427,6 +427,7 @@ define(function (require, exports, module) {
var testPath = SpecRunnerUtils.getTestPath("/spec/InlineEditorProviders-test-files"),
testWindow,
FileFilters,
+ FileSystem,
FindInFiles,
CommandManager,
$;
@@ -438,6 +439,7 @@ define(function (require, exports, module) {
// Load module instances from brackets.test
FileFilters = testWindow.brackets.test.FileFilters;
+ FileSystem = testWindow.brackets.test.FileSystem;
FindInFiles = testWindow.brackets.test.FindInFiles;
CommandManager = testWindow.brackets.test.CommandManager;
$ = testWindow.$;
@@ -448,6 +450,7 @@ define(function (require, exports, module) {
afterLast(function () {
testWindow = null;
+ FileSystem = null;
FileFilters = null;
FindInFiles = null;
CommandManager = null;
@@ -455,7 +458,7 @@ define(function (require, exports, module) {
SpecRunnerUtils.closeTestWindow();
});
- function openSearchBar() {
+ function openSearchBar(scope) {
// Make sure search bar from previous test has animated out fully
runs(function () {
waitsFor(function () {
@@ -463,7 +466,7 @@ define(function (require, exports, module) {
}, "search bar close");
});
runs(function () {
- waitsForDone(CommandManager.execute(Commands.EDIT_FIND_IN_FILES));
+ FindInFiles._doFindInFiles(scope);
});
}
@@ -506,11 +509,76 @@ define(function (require, exports, module) {
executeSearch("{1}");
});
runs(function () {
- expect(FindInFiles._searchResults[testPath + "/test1.css"]).toBeFalsy(); // *.css should have been excluded this time
+ // *.css should have been excluded this time
+ expect(FindInFiles._searchResults[testPath + "/test1.css"]).toBeFalsy();
expect(FindInFiles._searchResults[testPath + "/test1.html"]).toBeTruthy();
});
});
+ it("should respect filter when searching folder", function () {
+ var dirEntry = FileSystem.getDirectoryForPath(testPath);
+ openSearchBar(dirEntry);
+ runs(function () {
+ setExcludeCSSFiles();
+ });
+ runs(function () {
+ executeSearch("{1}");
+ });
+ runs(function () {
+ // *.css should have been excluded this time
+ expect(FindInFiles._searchResults[testPath + "/test1.css"]).toBeFalsy();
+ expect(FindInFiles._searchResults[testPath + "/test1.html"]).toBeTruthy();
+ });
+ });
+
+ it("should ignore filter when searching a single file", function () {
+ var fileEntry = FileSystem.getFileForPath(testPath + "/test1.css");
+ openSearchBar(fileEntry);
+ runs(function () {
+ // Cannot explicitly set *.css filter in dialog because button is hidden
+ // (which is verified here), but filter persists from previous test
+ expect($(".filter-picker button").is(":visible")).toBeFalsy();
+ });
+ runs(function () {
+ executeSearch("{1}");
+ });
+ runs(function () {
+ // ignore *.css exclusion since we're explicitly searching this file
+ expect(FindInFiles._searchResults[testPath + "/test1.css"]).toBeTruthy();
+ });
+ });
+
+ it("should show error when filter excludes all files", function () {
+ openSearchBar();
+ runs(function () {
+ // Launch filter editor
+ $(".filter-picker button").click();
+
+ // Edit the filter & confirm changes
+ $(".modal.instance textarea").val("test1.*\n*.css");
+ SpecRunnerUtils.clickDialogButton(Dialogs.DIALOG_BTN_OK);
+ });
+ runs(function () {
+ executeSearch("{1}");
+ });
+ runs(function () {
+ var $modalBar = $(".modal-bar");
+
+ // Dialog still showing
+ expect($modalBar.length).toBe(1);
+
+ // Error message displayed
+ expect($modalBar.find("#find-group div.error").is(":visible")).toBeTruthy();
+
+ // Search panel not showing
+ expect($("#search-results").is(":visible")).toBeFalsy();
+
+ // Close search bar
+ var $searchField = $modalBar.find("#find-group input");
+ SpecRunnerUtils.simulateKeyEvent(KeyEvent.DOM_VK_ESCAPE, "keydown", $searchField[0]);
+ });
+ });
+
it("should respect filter when editing code", function () {
openSearchBar();
runs(function () {
diff --git a/test/spec/FindReplace-test-files/bar.txt b/test/spec/FindReplace-test-files/bar.txt
new file mode 100644
index 00000000000..b071cf9ee9c
--- /dev/null
+++ b/test/spec/FindReplace-test-files/bar.txt
@@ -0,0 +1,3 @@
+bar.txt file
+
+This file should *not* show up in certain searches
diff --git a/test/spec/FindReplace-test-files/css/foo.css b/test/spec/FindReplace-test-files/css/foo.css
new file mode 100644
index 00000000000..02a7ad9ce7e
--- /dev/null
+++ b/test/spec/FindReplace-test-files/css/foo.css
@@ -0,0 +1,13 @@
+/* foo.css */
+body {
+ margin: 0;
+}
+h1, footer {
+ padding: 2px auto;
+}
+ul.foo {
+ list-style: none;
+}
+.bar {
+ font-size: large;
+}
diff --git a/test/spec/FindReplace-test-files/foo.html b/test/spec/FindReplace-test-files/foo.html
new file mode 100644
index 00000000000..1c7ead8038d
--- /dev/null
+++ b/test/spec/FindReplace-test-files/foo.html
@@ -0,0 +1,22 @@
+
+
+
+
+Foo
+
+
+
+
+
+
+ Foo
+ Intro to foo
+
+ It's all about the bar
+
+
+
diff --git a/test/spec/FindReplace-test-files/foo.js b/test/spec/FindReplace-test-files/foo.js
new file mode 100644
index 00000000000..e6951ce3fa2
--- /dev/null
+++ b/test/spec/FindReplace-test-files/foo.js
@@ -0,0 +1,13 @@
+/* Test comment */
+define(function (require, exports, module) {
+ var Foo = require("modules/Foo"),
+ Bar = require("modules/Bar"),
+ Baz = require("modules/Baz");
+
+ function callFoo() {
+
+ foo();
+
+ }
+
+}
diff --git a/test/spec/FindReplace-test.js b/test/spec/FindReplace-test.js
index 1c9cc97cb14..1bf5553d418 100644
--- a/test/spec/FindReplace-test.js
+++ b/test/spec/FindReplace-test.js
@@ -29,9 +29,9 @@ define(function (require, exports, module) {
'use strict';
var Commands = require("command/Commands"),
+ FindReplace = require("search/FindReplace"),
KeyEvent = require("utils/KeyEvent"),
- SpecRunnerUtils = require("spec/SpecRunnerUtils"),
- FindReplace = require("search/FindReplace");
+ SpecRunnerUtils = require("spec/SpecRunnerUtils");
var defaultContent = "/* Test comment */\n" +
"define(function (require, exports, module) {\n" +
@@ -552,6 +552,20 @@ define(function (require, exports, module) {
expectSelection(capitalFooSelections[0]);
});
+ it("should have a scroll track marker for every match", function () {
+ twCommandManager.execute(Commands.EDIT_FIND);
+
+ enterSearchText("foo");
+ expectHighlightedMatches(fooExpectedMatches);
+
+ var marks = testWindow.brackets.test.ScrollTrackMarkers._getTickmarks();
+ expect(marks.length).toEqual(fooExpectedMatches.length);
+
+ marks.forEach(function (mark, index) {
+ expect(mark.line).toEqual(fooExpectedMatches[index].start.line);
+ });
+ });
+
it("toggling case-sensitive option should update results immediately", function () {
myEditor.setCursorPos(0, 0);
@@ -787,6 +801,26 @@ define(function (require, exports, module) {
expectSelection(barExpectedMatches[0]);
});
+ it("should use empty initial query for single cursor selection", function () {
+ myEditor.setSelection({line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_START});
+ twCommandManager.execute(Commands.EDIT_FIND);
+ expect(getSearchField().val()).toEqual("");
+ });
+
+ it("should use empty initial query for multiple cursor selection", function () {
+ myEditor.setSelections([{start: {line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_START}, end: {line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_START}, primary: true},
+ {start: {line: 1, ch: 0}, end: {line: 1, ch: 0}}]);
+ twCommandManager.execute(Commands.EDIT_FIND);
+ expect(getSearchField().val()).toEqual("");
+ });
+
+ it("should get single selection as initial query", function () {
+ myEditor.setSelection({line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_START},
+ {line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_PAREN});
+ twCommandManager.execute(Commands.EDIT_FIND);
+ expect(getSearchField().val()).toEqual("require");
+ });
+
it("should get primary selection as initial query", function () {
myEditor.setSelections([{start: {line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_START}, end: {line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_PAREN}, primary: true},
{start: {line: 1, ch: 0}, end: {line: 1, ch: 1}}]);
@@ -1087,6 +1121,36 @@ define(function (require, exports, module) {
expect(/bar/i.test(myEditor.getSelectedText())).toBe(true);
});
});
+
+ it("should find and skip then replace string", function () {
+ runs(function () {
+ twCommandManager.execute(Commands.EDIT_REPLACE);
+ enterSearchText("foo");
+ enterReplaceText("bar");
+
+ expectSelection(fooExpectedMatches[0]);
+ expect(/foo/i.test(myEditor.getSelectedText())).toBe(true);
+
+ // Skip first
+ expect(tw$("#find-next").is(":enabled")).toBe(true);
+ tw$("#find-next").click();
+
+ expectSelection(fooExpectedMatches[1]);
+ expect(/foo/i.test(myEditor.getSelectedText())).toBe(true);
+
+ // Replace second
+ expect(tw$("#replace-yes").is(":enabled")).toBe(true);
+ tw$("#replace-yes").click();
+
+ expectSelection(fooExpectedMatches[2]);
+
+ myEditor.setSelection(fooExpectedMatches[0].start, fooExpectedMatches[0].end);
+ expect(/foo/i.test(myEditor.getSelectedText())).toBe(true);
+
+ myEditor.setSelection(fooExpectedMatches[1].start, fooExpectedMatches[1].end);
+ expect(/bar/i.test(myEditor.getSelectedText())).toBe(true);
+ });
+ });
it("should use replace keyboard shortcut for single Replace while search bar open", function () {
runs(function () {
@@ -1267,6 +1331,40 @@ define(function (require, exports, module) {
describe("Search -> Replace All", function () {
+ it("should find and replace all", function () {
+ runs(function () {
+ var searchText = "require",
+ replaceText = "brackets.getModule";
+ twCommandManager.execute(Commands.EDIT_REPLACE);
+ enterSearchText(searchText);
+ enterReplaceText(replaceText);
+
+ expectSelection({start: {line: 1, ch: 17}, end: {line: 1, ch: 17 + searchText.length}});
+ expect(myEditor.getSelectedText()).toBe(searchText);
+
+ expect(tw$("#replace-all").is(":enabled")).toBe(true);
+ tw$("#replace-all").click();
+ tw$(".replace-checked").click();
+
+ myEditor.setSelection({line: 1, ch: 17}, {line: 1, ch: 17 + replaceText.length});
+ expect(myEditor.getSelectedText()).toBe(replaceText);
+
+ // Note: LINE_FIRST_REQUIRE and CH_REQUIRE_START refer to first call to "require",
+ // but not first instance of "require" in text
+ myEditor.setSelection({line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_START},
+ {line: LINE_FIRST_REQUIRE, ch: CH_REQUIRE_START + replaceText.length});
+ expect(myEditor.getSelectedText()).toBe(replaceText);
+
+ myEditor.setSelection({line: LINE_FIRST_REQUIRE + 1, ch: CH_REQUIRE_START},
+ {line: LINE_FIRST_REQUIRE + 1, ch: CH_REQUIRE_START + replaceText.length});
+ expect(myEditor.getSelectedText()).toBe(replaceText);
+
+ myEditor.setSelection({line: LINE_FIRST_REQUIRE + 2, ch: CH_REQUIRE_START},
+ {line: LINE_FIRST_REQUIRE + 2, ch: CH_REQUIRE_START + replaceText.length});
+ expect(myEditor.getSelectedText()).toBe(replaceText);
+ });
+ });
+
it("should find all regexps and replace them with $n", function () {
runs(function () {
twCommandManager.execute(Commands.EDIT_REPLACE);
@@ -1430,5 +1528,332 @@ define(function (require, exports, module) {
});
});
});
-
+
+
+ describe("FindInFiles", function () {
+
+ this.category = "integration";
+
+ var testPath = SpecRunnerUtils.getTestPath("/spec/FindReplace-test-files"),
+ CommandManager,
+ DocumentManager,
+ EditorManager,
+ FileSystem,
+ FindInFiles,
+ testWindow,
+ $;
+
+ beforeFirst(function () {
+ // Create a new window that will be shared by ALL tests in this spec.
+ SpecRunnerUtils.createTestWindowAndRun(this, function (w) {
+ testWindow = w;
+
+ // Load module instances from brackets.test
+ CommandManager = testWindow.brackets.test.CommandManager;
+ DocumentManager = testWindow.brackets.test.DocumentManager;
+ EditorManager = testWindow.brackets.test.EditorManager;
+ FileSystem = testWindow.brackets.test.FileSystem;
+ FindInFiles = testWindow.brackets.test.FindInFiles;
+ CommandManager = testWindow.brackets.test.CommandManager;
+ $ = testWindow.$;
+
+ SpecRunnerUtils.loadProjectInTestWindow(testPath);
+ });
+ });
+
+ afterLast(function () {
+ CommandManager = null;
+ DocumentManager = null;
+ EditorManager = null;
+ FileSystem = null;
+ FindInFiles = null;
+ $ = null;
+ testWindow = null;
+ SpecRunnerUtils.closeTestWindow();
+ });
+
+ function openSearchBar(scope) {
+ // Make sure search bar from previous test has animated out fully
+ runs(function () {
+ waitsFor(function () {
+ return $(".modal-bar").length === 0;
+ }, "search bar close");
+ });
+ runs(function () {
+ FindInFiles._doFindInFiles(scope);
+ });
+ }
+
+ function executeSearch(searchString) {
+ var $searchField = $(".modal-bar #find-group input");
+ $searchField.val(searchString).trigger("input");
+ SpecRunnerUtils.simulateKeyEvent(KeyEvent.DOM_VK_RETURN, "keydown", $searchField[0]);
+ waitsFor(function () {
+ return FindInFiles._searchResults;
+ }, "Find in Files done");
+ }
+
+
+ it("should find all occurences in project", function () {
+ openSearchBar();
+ runs(function () {
+ executeSearch("foo");
+ });
+
+ runs(function () {
+ var fileResults = FindInFiles._searchResults[testPath + "/bar.txt"];
+ expect(fileResults).toBeFalsy();
+
+ fileResults = FindInFiles._searchResults[testPath + "/foo.html"];
+ expect(fileResults).toBeTruthy();
+ expect(fileResults.matches.length).toBe(7);
+
+ fileResults = FindInFiles._searchResults[testPath + "/foo.js"];
+ expect(fileResults).toBeTruthy();
+ expect(fileResults.matches.length).toBe(4);
+
+ fileResults = FindInFiles._searchResults[testPath + "/css/foo.css"];
+ expect(fileResults).toBeTruthy();
+ expect(fileResults.matches.length).toBe(3);
+ });
+ });
+
+ it("should find all occurences in folder", function () {
+ var dirEntry = FileSystem.getDirectoryForPath(testPath + "/css/");
+ openSearchBar(dirEntry);
+ runs(function () {
+ executeSearch("foo");
+ });
+
+ runs(function () {
+ var fileResults = FindInFiles._searchResults[testPath + "/bar.txt"];
+ expect(fileResults).toBeFalsy();
+
+ fileResults = FindInFiles._searchResults[testPath + "/foo.html"];
+ expect(fileResults).toBeFalsy();
+
+ fileResults = FindInFiles._searchResults[testPath + "/foo.js"];
+ expect(fileResults).toBeFalsy();
+
+ fileResults = FindInFiles._searchResults[testPath + "/css/foo.css"];
+ expect(fileResults).toBeTruthy();
+ expect(fileResults.matches.length).toBe(3);
+ });
+ });
+
+ it("should find all occurences in single file", function () {
+ var fileEntry = FileSystem.getFileForPath(testPath + "/foo.js");
+ openSearchBar(fileEntry);
+ runs(function () {
+ executeSearch("foo");
+ });
+
+ runs(function () {
+ var fileResults = FindInFiles._searchResults[testPath + "/bar.txt"];
+ expect(fileResults).toBeFalsy();
+
+ fileResults = FindInFiles._searchResults[testPath + "/foo.html"];
+ expect(fileResults).toBeFalsy();
+
+ fileResults = FindInFiles._searchResults[testPath + "/foo.js"];
+ expect(fileResults).toBeTruthy();
+ expect(fileResults.matches.length).toBe(4);
+
+ fileResults = FindInFiles._searchResults[testPath + "/css/foo.css"];
+ expect(fileResults).toBeFalsy();
+ });
+ });
+
+ it("should find start and end positions", function () {
+ var filePath = testPath + "/foo.js",
+ fileEntry = FileSystem.getFileForPath(filePath);
+
+ openSearchBar(fileEntry);
+ runs(function () {
+ executeSearch("callFoo");
+ });
+
+ runs(function () {
+ var fileResults = FindInFiles._searchResults[filePath];
+ expect(fileResults).toBeTruthy();
+ expect(fileResults.matches.length).toBe(1);
+
+ var match = fileResults.matches[0];
+ expect(match.start.ch).toBe(13);
+ expect(match.start.line).toBe(6);
+ expect(match.end.ch).toBe(20);
+ expect(match.end.line).toBe(6);
+ });
+ });
+
+ it("should dismiss dialog and show panel when there are results", function () {
+ var filePath = testPath + "/foo.js",
+ fileEntry = FileSystem.getFileForPath(filePath);
+
+ openSearchBar(fileEntry);
+ runs(function () {
+ executeSearch("callFoo");
+ });
+
+ waitsFor(function () {
+ return ($(".modal-bar").length === 0);
+ }, "search bar close");
+
+ runs(function () {
+ var fileResults = FindInFiles._searchResults[filePath];
+ expect(fileResults).toBeTruthy();
+ expect($("#search-results").is(":visible")).toBeTruthy();
+ expect($(".modal-bar").length).toBe(0);
+ });
+ });
+
+ it("should keep dialog and not show panel when there are no results", function () {
+ var filePath = testPath + "/bar.txt",
+ fileEntry = FileSystem.getFileForPath(filePath);
+
+ openSearchBar(fileEntry);
+ runs(function () {
+ executeSearch("abcdefghi");
+ });
+
+ waitsFor(function () {
+ return (FindInFiles._searchResults);
+ }, "search complete");
+
+ runs(function () {
+ var result, resultFound = false;
+
+ // verify _searchResults Object is empty
+ for (result in FindInFiles._searchResults) {
+ if (FindInFiles._searchResults.hasOwnProperty(result)) {
+ resultFound = true;
+ }
+ }
+ expect(resultFound).toBe(false);
+
+ expect($("#search-results").is(":visible")).toBeFalsy();
+ expect($(".modal-bar").length).toBe(1);
+
+ // Close search bar
+ var $searchField = $(".modal-bar #find-group input");
+ SpecRunnerUtils.simulateKeyEvent(KeyEvent.DOM_VK_ESCAPE, "keydown", $searchField[0]);
+ });
+ });
+
+ it("should open file in editor and select text when a result is clicked", function () {
+ var filePath = testPath + "/foo.html",
+ fileEntry = FileSystem.getFileForPath(filePath);
+
+ openSearchBar(fileEntry);
+ runs(function () {
+ executeSearch("foo");
+ });
+
+ runs(function () {
+ // Verify no current document
+ var editor = EditorManager.getActiveEditor();
+ expect(editor).toBeFalsy();
+
+ // Get panel
+ var $searchResults = $("#search-results");
+ expect($searchResults.is(":visible")).toBeTruthy();
+
+ // Get list in panel
+ var $panelResults = $searchResults.find("table.bottom-panel-table tr");
+ expect($panelResults.length).toBe(8); // 7 hits + 1 file section
+
+ // First item in list is file section
+ expect($($panelResults[0]).hasClass("file-section")).toBeTruthy();
+
+ // Click second item which is first hit
+ var $firstHit = $($panelResults[1]);
+ expect($firstHit.hasClass("file-section")).toBeFalsy();
+ $firstHit.click();
+
+ // Verify current document
+ editor = EditorManager.getActiveEditor();
+ expect(editor.document.file.fullPath).toEqual(filePath);
+
+ // Verify selection
+ expect(editor.getSelectedText().toLowerCase() === "foo");
+ CommandManager.execute(Commands.FILE_CLOSE_ALL);
+ });
+ });
+
+ it("should open file in working set when a result is double-clicked", function () {
+ var filePath = testPath + "/foo.js",
+ fileEntry = FileSystem.getFileForPath(filePath);
+
+ openSearchBar(fileEntry);
+ runs(function () {
+ executeSearch("foo");
+ });
+
+ runs(function () {
+ // Verify document is not yet in working set
+ expect(DocumentManager.findInWorkingSet(filePath)).toBe(-1);
+
+ // Get list in panel
+ var $panelResults = $("#search-results table.bottom-panel-table tr");
+ expect($panelResults.length).toBe(5); // 4 hits + 1 file section
+
+ // Double-click second item which is first hit
+ var $firstHit = $($panelResults[1]);
+ expect($firstHit.hasClass("file-section")).toBeFalsy();
+ $firstHit.dblclick();
+
+ // Verify document is now in working set
+ expect(DocumentManager.findInWorkingSet(filePath)).not.toBe(-1);
+ CommandManager.execute(Commands.FILE_CLOSE_ALL);
+ });
+ });
+
+ it("should update results when a result in a file is edited", function () {
+ var filePath = testPath + "/foo.html",
+ fileEntry = FileSystem.getFileForPath(filePath),
+ panelListLen = 8, // 7 hits + 1 file section
+ $panelResults;
+
+ openSearchBar(fileEntry);
+ runs(function () {
+ executeSearch("foo");
+ });
+
+ runs(function () {
+ // Verify document is not yet in working set
+ expect(DocumentManager.findInWorkingSet(filePath)).toBe(-1);
+
+ // Get list in panel
+ $panelResults = $("#search-results table.bottom-panel-table tr");
+ expect($panelResults.length).toBe(panelListLen);
+
+ // Double-click second item which is first hit
+ var $firstHit = $($panelResults[1]);
+ expect($firstHit.hasClass("file-section")).toBeFalsy();
+ $firstHit.dblclick();
+
+ // Verify current document & selection
+ var editor = EditorManager.getActiveEditor();
+ expect(editor.document.file.fullPath).toEqual(filePath);
+ expect(editor.getSelectedText().toLowerCase() === "foo");
+
+ // Edit text to remove hit from file
+ var sel = editor.getSelection();
+ editor.document.replaceRange("Bar", sel.start, sel.end);
+ });
+
+ // Panel is updated asynchronously
+ waitsFor(function () {
+ $panelResults = $("#search-results table.bottom-panel-table tr");
+ return ($panelResults.length < panelListLen);
+ }, "Results panel updated");
+
+ runs(function () {
+ // Verify list automatically updated
+ expect($panelResults.length).toBe(panelListLen - 1);
+
+ CommandManager.execute(Commands.FILE_CLOSE_ALL);
+ });
+ });
+ });
});