Chromium Code Reviews| 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..fb060dbd8ffef157f652faf4760ff79325f9998b |
| --- /dev/null |
| +++ b/pkg/analysis_server/test/src/watch_manager_test.dart |
| @@ -0,0 +1,373 @@ |
| +// 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 '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 'dart:async'; |
| + |
| +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; |
| + |
| + /** |
| + * 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_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_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', ''); |
| + _expectEvent(ChangeType.ADD, newFile.path, [token1, token2]); |
| + } |
| + |
| + 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_unadded() { |
| + Folder folder = provider.getFolder('/a/b'); |
| + Token token = new Token('token'); |
| + manager.removeFolder(folder, token); |
| + |
| + provider.newFile('/a/b/lib.dart', ''); |
| + _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', ''); |
| + _expectNoEvent(); |
| + } |
| + |
| + 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', ''); |
| + _expectEvent(ChangeType.ADD, newFile.path, [token1]); |
| + } |
| + |
| + Future _expectEvent(ChangeType expectedType, String expectedPath, |
| + List<Token> expectedTokens) async { |
| + await new Future.delayed(Duration.ZERO); |
| + WatchEvent event = listener.event; |
| + expect(event, isNotNull); |
| + expect(event.type, expectedType); |
| + expect(event.path, expectedPath); |
| + expect(listener.tokens, unorderedEquals(expectedTokens)); |
| + } |
| + |
| + Future _expectNoEvent() async { |
| + await new Future.delayed(Duration.ZERO); |
|
Paul Berry
2015/07/19 18:38:34
Consider using pumpEventQueue(), which makes the t
Brian Wilkerson
2015/07/19 21:24:21
Done
|
| + 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_forEachChild_children() { |
| + WatchNode rootNode = new WatchNode(null); |
| + WatchNode child1 = new WatchNode(provider.getFolder('/a')); |
| + WatchNode child2 = new WatchNode(provider.getFolder('/b')); |
| + WatchNode child3 = new WatchNode(provider.getFolder('/c')); |
| + rootNode.insert(child1); |
| + rootNode.insert(child2); |
| + rootNode.insert(child3); |
| + |
| + List<String> expectedPaths = <String>['/a', '/b', '/c']; |
| + rootNode.forEachChild((WatchNode node) { |
| + expect(expectedPaths.remove(node.folder.path), isTrue); |
| + }); |
| + expect(expectedPaths, isEmpty); |
| + } |
| + |
| + void test_forEachChild_noChildren() { |
| + WatchNode rootNode = new WatchNode(null); |
| + |
| + int count = 0; |
| + rootNode.forEachChild((WatchNode node) { |
| + count++; |
| + }); |
| + expect(count, 0); |
| + } |
| + |
| + 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_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_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); |
| + } |
| +} |