Index: pkg/analysis_server/test/src/watch_manager_test.dart |
diff --git a/pkg/analysis_server/test/src/watch_manager_test.dart b/pkg/analysis_server/test/src/watch_manager_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8d1c4e2102528cafeeae90b96e752b8ef002ddab |
--- /dev/null |
+++ b/pkg/analysis_server/test/src/watch_manager_test.dart |
@@ -0,0 +1,360 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library test.src.watch_manager_test; |
+ |
+import 'dart:async'; |
+ |
+import 'package:analysis_server/src/watch_manager.dart'; |
+import 'package:analyzer/file_system/file_system.dart'; |
+import 'package:analyzer/file_system/memory_file_system.dart'; |
+import 'package:test_reflective_loader/test_reflective_loader.dart'; |
+import 'package:unittest/unittest.dart'; |
+import 'package:watcher/watcher.dart'; |
+ |
+import '../mocks.dart'; |
+ |
+main() { |
+ groupSep = ' | '; |
+ defineReflectiveTests(WatchManagerTest); |
+ defineReflectiveTests(WatchNodeTest); |
+} |
+ |
+/** |
+ * Tokens that can be used for testing purposes. |
+ */ |
+class Token { |
+ /** |
+ * A name used for debugging. |
+ */ |
+ final String name; |
+ |
+ /** |
+ * Initialize a newly created token to have the given name. |
+ */ |
+ Token(this.name); |
+ |
+ @override |
+ String toString() => name; |
+} |
+ |
+/** |
+ * A listener that captures the state of watch events so that they can be |
+ * tested. |
+ */ |
+class WatchListener { |
+ /** |
+ * The event that was passed to the listener method. |
+ */ |
+ WatchEvent event; |
+ |
+ /** |
+ * The tokens that were passed to the listener method. |
+ */ |
+ List<Token> tokens; |
+ |
+ /** |
+ * Clear the state so that we can distinguish between not receiving an event |
+ * and receiving the wrong event. |
+ */ |
+ void clear() { |
+ this.event = null; |
+ this.tokens = null; |
+ } |
+ |
+ /** |
+ * The listener method. |
+ */ |
+ void handleWatchEvent(WatchEvent event, List<Token> tokens) { |
+ this.event = event; |
+ this.tokens = tokens; |
+ } |
+} |
+ |
+@reflectiveTest |
+class WatchManagerTest { |
+ MemoryResourceProvider provider; |
+ WatchListener listener; |
+ WatchManager<Token> manager; |
+ |
+ void setUp() { |
+ provider = new MemoryResourceProvider(); |
+ listener = new WatchListener(); |
+ manager = new WatchManager<Token>(provider, listener.handleWatchEvent); |
+ } |
+ |
+ Future test_addFolder_folderAndSubfolder() async { |
+ Folder topFolder = provider.getFolder('/a/b'); |
+ Folder childFolder = provider.getFolder('/a/b/c/d'); |
+ Token topToken = new Token('topToken'); |
+ Token childToken = new Token('childToken'); |
+ manager.addFolder(topFolder, topToken); |
+ manager.addFolder(childFolder, childToken); |
+ |
+ File newFile1 = provider.newFile('/a/b/c/lib.dart', ''); |
+ await _expectEvent(ChangeType.ADD, newFile1.path, [topToken]); |
+ |
+ File newFile2 = provider.newFile('/a/b/c/d/lib.dart', ''); |
+ _expectEvent(ChangeType.ADD, newFile2.path, [topToken, childToken]); |
+ } |
+ |
+ Future test_addFolder_singleFolder_multipleTokens() { |
+ Folder folder = provider.getFolder('/a/b'); |
+ Token token1 = new Token('token1'); |
+ Token token2 = new Token('token2'); |
+ manager.addFolder(folder, token1); |
+ manager.addFolder(folder, token2); |
+ |
+ File newFile = provider.newFile('/a/b/lib.dart', ''); |
+ return _expectEvent(ChangeType.ADD, newFile.path, [token1, token2]); |
+ } |
+ |
+ Future test_addFolder_singleFolder_singleToken() async { |
+ Folder folder = provider.getFolder('/a/b'); |
+ Token token = new Token('token'); |
+ manager.addFolder(folder, token); |
+ |
+ Folder newFolder = provider.newFolder('/a/b/c'); |
+ await _expectEvent(ChangeType.ADD, newFolder.path, [token]); |
+ |
+ File newFile = provider.newFile('/a/b/c/lib.dart', ''); |
+ _expectEvent(ChangeType.ADD, newFile.path, [token]); |
+ } |
+ |
+ Future test_addFolder_unrelatedFolders() async { |
+ Folder folder1 = provider.getFolder('/a/b'); |
+ Folder folder2 = provider.getFolder('/c/d'); |
+ Token token1 = new Token('token1'); |
+ Token token2 = new Token('token2'); |
+ manager.addFolder(folder1, token1); |
+ manager.addFolder(folder2, token2); |
+ |
+ File newFile1 = provider.newFile('/a/b/lib.dart', ''); |
+ await _expectEvent(ChangeType.ADD, newFile1.path, [token1]); |
+ |
+ File newFile2 = provider.newFile('/c/d/lib.dart', ''); |
+ _expectEvent(ChangeType.ADD, newFile2.path, [token2]); |
+ } |
+ |
+ void test_creation() { |
+ expect(manager, isNotNull); |
+ } |
+ |
+ Future test_removeFolder_multipleTokens() { |
+ Folder folder = provider.getFolder('/a/b'); |
+ Token token1 = new Token('token1'); |
+ Token token2 = new Token('token2'); |
+ manager.addFolder(folder, token1); |
+ manager.addFolder(folder, token2); |
+ manager.removeFolder(folder, token2); |
+ |
+ File newFile = provider.newFile('/a/b/lib.dart', ''); |
+ return _expectEvent(ChangeType.ADD, newFile.path, [token1]); |
+ } |
+ |
+ Future test_removeFolder_unadded() { |
+ Folder folder = provider.getFolder('/a/b'); |
+ Token token = new Token('token'); |
+ expect(() => manager.removeFolder(folder, token), throws); |
+ |
+ provider.newFile('/a/b/lib.dart', ''); |
+ return _expectNoEvent(); |
+ } |
+ |
+ Future test_removeFolder_withChildren() async { |
+ Folder topFolder = provider.getFolder('/a/b'); |
+ Folder childFolder = provider.getFolder('/a/b/c/d'); |
+ Token topToken = new Token('topToken'); |
+ Token childToken = new Token('childToken'); |
+ manager.addFolder(topFolder, topToken); |
+ manager.addFolder(childFolder, childToken); |
+ manager.removeFolder(topFolder, topToken); |
+ |
+ File newFile = provider.newFile('/a/b/c/d/lib.dart', ''); |
+ await _expectEvent(ChangeType.ADD, newFile.path, [childToken]); |
+ |
+ provider.newFile('/a/b/lib.dart', ''); |
+ _expectNoEvent(); |
+ } |
+ |
+ Future test_removeFolder_withNoChildren() { |
+ Folder folder = provider.getFolder('/a/b'); |
+ Token token = new Token('token'); |
+ manager.addFolder(folder, token); |
+ manager.removeFolder(folder, token); |
+ |
+ provider.newFile('/a/b/lib.dart', ''); |
+ return _expectNoEvent(); |
+ } |
+ |
+ Future _expectEvent(ChangeType expectedType, String expectedPath, |
+ List<Token> expectedTokens) async { |
+ await pumpEventQueue(); |
+ WatchEvent event = listener.event; |
+ expect(event, isNotNull); |
+ expect(event.type, expectedType); |
+ expect(event.path, expectedPath); |
+ expect(listener.tokens, unorderedEquals(expectedTokens)); |
+ listener.clear(); |
+ } |
+ |
+ Future _expectNoEvent() async { |
+ await pumpEventQueue(); |
+ expect(listener.event, isNull); |
+ expect(listener.tokens, isNull); |
+ } |
+} |
+ |
+@reflectiveTest |
+class WatchNodeTest { |
+ MemoryResourceProvider provider = new MemoryResourceProvider(); |
+ |
+ void test_creation_folder() { |
+ Folder folder = provider.getFolder('/a/b'); |
+ WatchNode node = new WatchNode(folder); |
+ expect(node, isNotNull); |
+ expect(node.children, isEmpty); |
+ expect(node.folder, folder); |
+ expect(node.parent, isNull); |
+ expect(node.subscription, isNull); |
+ expect(node.tokens, isEmpty); |
+ } |
+ |
+ void test_creation_noFolder() { |
+ WatchNode node = new WatchNode(null); |
+ expect(node, isNotNull); |
+ expect(node.children, isEmpty); |
+ expect(node.folder, isNull); |
+ expect(node.parent, isNull); |
+ expect(node.subscription, isNull); |
+ expect(node.tokens, isEmpty); |
+ } |
+ |
+ void test_delete_nested_child() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); |
+ WatchNode grandchildNode = new WatchNode(provider.getFolder('/a/b/c/d/e')); |
+ rootNode.insert(topNode); |
+ rootNode.insert(childNode); |
+ rootNode.insert(grandchildNode); |
+ |
+ childNode.delete(); |
+ expect(rootNode.children, equals([topNode])); |
+ expect(topNode.children, equals([grandchildNode])); |
+ expect(topNode.parent, rootNode); |
+ expect(grandchildNode.parent, topNode); |
+ } |
+ |
+ void test_delete_nested_noChild() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); |
+ rootNode.insert(topNode); |
+ rootNode.insert(childNode); |
+ |
+ childNode.delete(); |
+ expect(rootNode.children, equals([topNode])); |
+ expect(topNode.children, isEmpty); |
+ expect(topNode.parent, rootNode); |
+ } |
+ |
+ void test_delete_top_child() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); |
+ rootNode.insert(topNode); |
+ rootNode.insert(childNode); |
+ |
+ topNode.delete(); |
+ expect(rootNode.children, equals([childNode])); |
+ expect(childNode.parent, rootNode); |
+ } |
+ |
+ void test_delete_top_noChild() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ rootNode.insert(topNode); |
+ |
+ topNode.delete(); |
+ expect(rootNode.children, isEmpty); |
+ } |
+ |
+ void test_findParent_childOfLeaf() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ rootNode.insert(topNode); |
+ |
+ expect(rootNode.findParent('/a/b/c'), topNode); |
+ } |
+ |
+ void test_findParent_childOfNonLeaf() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); |
+ rootNode.insert(topNode); |
+ rootNode.insert(childNode); |
+ |
+ expect(rootNode.findParent('/a/b/c'), topNode); |
+ } |
+ |
+ void test_findParent_noMatch() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ rootNode.insert(topNode); |
+ |
+ expect(rootNode.findParent('/c/d'), rootNode); |
+ } |
+ |
+ void test_insert_intermediate_afterParentAndChild() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); |
+ WatchNode intermediateNode = new WatchNode(provider.getFolder('/a/b/c')); |
+ |
+ rootNode.insert(topNode); |
+ rootNode.insert(childNode); |
+ rootNode.insert(intermediateNode); |
+ expect(topNode.parent, rootNode); |
+ expect(topNode.children, equals([intermediateNode])); |
+ expect(intermediateNode.parent, topNode); |
+ expect(intermediateNode.children, equals([childNode])); |
+ expect(childNode.parent, intermediateNode); |
+ expect(childNode.children, isEmpty); |
+ } |
+ |
+ void test_insert_nested_afterParent() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); |
+ |
+ rootNode.insert(topNode); |
+ rootNode.insert(childNode); |
+ expect(childNode.parent, topNode); |
+ expect(childNode.children, isEmpty); |
+ expect(topNode.children, equals([childNode])); |
+ } |
+ |
+ void test_insert_nested_beforeParent() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d')); |
+ |
+ rootNode.insert(childNode); |
+ rootNode.insert(topNode); |
+ expect(childNode.parent, topNode); |
+ expect(childNode.children, isEmpty); |
+ expect(topNode.children, equals([childNode])); |
+ } |
+ |
+ void test_insert_top() { |
+ WatchNode rootNode = new WatchNode(null); |
+ WatchNode topNode = new WatchNode(provider.getFolder('/a/b')); |
+ |
+ rootNode.insert(topNode); |
+ expect(rootNode.children, equals([topNode])); |
+ expect(topNode.parent, rootNode); |
+ expect(topNode.children, isEmpty); |
+ } |
+} |