Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Unified Diff: pkg/analysis_server/test/context_directory_manager_test.dart

Issue 450643005: Churn-only CL for ContextDirectoryManager. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analysis_server/lib/src/context_directory_manager.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analysis_server/test/context_directory_manager_test.dart
diff --git a/pkg/analysis_server/test/context_directory_manager_test.dart b/pkg/analysis_server/test/context_directory_manager_test.dart
index f33b2f8b6989283432f440b7890ff90c21d0768d..82793f41b7daec8639ecd46c301f61e8fc41a353 100644
--- a/pkg/analysis_server/test/context_directory_manager_test.dart
+++ b/pkg/analysis_server/test/context_directory_manager_test.dart
@@ -4,21 +4,288 @@
library test.context.directory.manager;
-import 'mocks.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analysis_server/src/context_directory_manager.dart';
import 'package:analysis_server/src/package_map_provider.dart';
+import 'package:analysis_testing/reflective_tests.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:path/path.dart';
import 'package:unittest/unittest.dart';
-class TestContextDirectoryManager extends ContextDirectoryManager {
- TestContextDirectoryManager(
- MemoryResourceProvider resourceProvider, PackageMapProvider packageMapProvider)
- : super(resourceProvider, packageMapProvider);
+import 'mocks.dart';
+
+
+main() {
+ groupSep = ' | ';
+ runReflectiveTests(ContextDirectoryManagerTest);
+}
+
+
+@ReflectiveTestCase()
+class ContextDirectoryManagerTest {
+ TestContextDirectoryManager manager;
+ MemoryResourceProvider resourceProvider;
+ MockPackageMapProvider packageMapProvider;
+
+ String projPath = '/my/proj';
+
+ void setUp() {
+ resourceProvider = new MemoryResourceProvider();
+ packageMapProvider = new MockPackageMapProvider();
+ manager = new TestContextDirectoryManager(
+ resourceProvider,
+ packageMapProvider);
+ resourceProvider.newFolder(projPath);
+ }
+
+ test_ignoreFilesInPackagesFolder() {
+ // create a context with a pubspec.yaml file
+ String pubspecPath = posix.join(projPath, 'pubspec.yaml');
+ resourceProvider.newFile(pubspecPath, 'pubspec');
+ // create a file in the "packages" folder
+ String filePath1 = posix.join(projPath, 'packages', 'file1.dart');
+ resourceProvider.newFile(filePath1, 'contents');
+ // "packages" files are ignored initially
+ manager.setRoots(<String>[projPath], <String>[]);
+ expect(manager.currentContextFilePaths[projPath], isEmpty);
+ // "packages" files are ignored during watch
+ String filePath2 = posix.join(projPath, 'packages', 'file2.dart');
+ resourceProvider.newFile(filePath2, 'contents');
+ return pumpEventQueue().then((_) {
+ expect(manager.currentContextFilePaths[projPath], isEmpty);
+ });
+ }
+
+ void test_isInAnalysisRoot_inRoot() {
+ manager.setRoots(<String>[projPath], <String>[]);
+ expect(manager.isInAnalysisRoot('$projPath/test.dart'), isTrue);
+ }
+
+ void test_isInAnalysisRoot_notInRoot() {
+ manager.setRoots(<String>[projPath], <String>[]);
+ expect(manager.isInAnalysisRoot('/test.dart'), isFalse);
+ }
+
+ void test_setRoots_addFolderWithDartFile() {
+ String filePath = posix.join(projPath, 'foo.dart');
+ resourceProvider.newFile(filePath, 'contents');
+ manager.setRoots(<String>[projPath], <String>[]);
+ // verify
+ var filePaths = manager.currentContextFilePaths[projPath];
+ expect(filePaths, hasLength(1));
+ expect(filePaths, contains(filePath));
+ }
+
+ void test_setRoots_addFolderWithDartFileInSubfolder() {
+ String filePath = posix.join(projPath, 'foo', 'bar.dart');
+ resourceProvider.newFile(filePath, 'contents');
+ manager.setRoots(<String>[projPath], <String>[]);
+ // verify
+ var filePaths = manager.currentContextFilePaths[projPath];
+ expect(filePaths, hasLength(1));
+ expect(filePaths, contains(filePath));
+ }
+
+ void test_setRoots_addFolderWithDummyLink() {
+ String filePath = posix.join(projPath, 'foo.dart');
+ resourceProvider.newDummyLink(filePath);
+ manager.setRoots(<String>[projPath], <String>[]);
+ // verify
+ var filePaths = manager.currentContextFilePaths[projPath];
+ expect(filePaths, isEmpty);
+ }
+
+ void test_setRoots_addFolderWithPubspec() {
+ String pubspecPath = posix.join(projPath, 'pubspec.yaml');
+ resourceProvider.newFile(pubspecPath, 'pubspec');
+ manager.setRoots(<String>[projPath], <String>[]);
+ // verify
+ expect(manager.currentContextPaths, hasLength(1));
+ expect(manager.currentContextPaths, contains(projPath));
+ expect(manager.currentContextFilePaths[projPath], hasLength(0));
+ }
+
+ void test_setRoots_addFolderWithoutPubspec() {
+ packageMapProvider.packageMap = null;
+ manager.setRoots(<String>[projPath], <String>[]);
+ // verify
+ expect(manager.currentContextPaths, hasLength(1));
+ expect(manager.currentContextPaths, contains(projPath));
+ expect(manager.currentContextFilePaths[projPath], hasLength(0));
+ }
+
+ void test_setRoots_newlyAddedFoldersGetProperPackageMap() {
+ String packagePath = '/package/foo';
+ Folder packageFolder = resourceProvider.newFolder(packagePath);
+ packageMapProvider.packageMap = {
+ 'foo': [packageFolder]
+ };
+ manager.setRoots(<String>[projPath], <String>[]);
+ expect(
+ manager.currentContextPackageMaps[projPath],
+ equals(packageMapProvider.packageMap));
+ }
+
+ void test_setRoots_removeFolderWithPubspec() {
+ // create a pubspec
+ String pubspecPath = posix.join(projPath, 'pubspec.yaml');
+ resourceProvider.newFile(pubspecPath, 'pubspec');
+ // add one root - there is a context
+ manager.setRoots(<String>[projPath], <String>[]);
+ expect(manager.currentContextPaths, hasLength(1));
+ // set empty roots - no contexts
+ manager.setRoots(<String>[], <String>[]);
+ expect(manager.currentContextPaths, hasLength(0));
+ expect(manager.currentContextFilePaths, hasLength(0));
+ }
+
+ void test_setRoots_removeFolderWithoutPubspec() {
+ packageMapProvider.packageMap = null;
+ // add one root - there is a context
+ manager.setRoots(<String>[projPath], <String>[]);
+ expect(manager.currentContextPaths, hasLength(1));
+ // set empty roots - no contexts
+ manager.setRoots(<String>[], <String>[]);
+ expect(manager.currentContextPaths, hasLength(0));
+ expect(manager.currentContextFilePaths, hasLength(0));
+ }
+
+ test_watch_addDummyLink() {
+ manager.setRoots(<String>[projPath], <String>[]);
+ // empty folder initially
+ Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+ expect(filePaths, isEmpty);
+ // add link
+ String filePath = posix.join(projPath, 'foo.dart');
+ resourceProvider.newDummyLink(filePath);
+ // the link was ignored
+ return pumpEventQueue().then((_) {
+ expect(filePaths, isEmpty);
+ });
+ }
+
+ test_watch_addFile() {
+ manager.setRoots(<String>[projPath], <String>[]);
+ // empty folder initially
+ Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+ expect(filePaths, hasLength(0));
+ // add file
+ String filePath = posix.join(projPath, 'foo.dart');
+ resourceProvider.newFile(filePath, 'contents');
+ // the file was added
+ return pumpEventQueue().then((_) {
+ expect(filePaths, hasLength(1));
+ expect(filePaths, contains(filePath));
+ });
+ }
+
+ test_watch_addFileInSubfolder() {
+ manager.setRoots(<String>[projPath], <String>[]);
+ // empty folder initially
+ Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+ expect(filePaths, hasLength(0));
+ // add file in subfolder
+ String filePath = posix.join(projPath, 'foo', 'bar.dart');
+ resourceProvider.newFile(filePath, 'contents');
+ // the file was added
+ return pumpEventQueue().then((_) {
+ expect(filePaths, hasLength(1));
+ expect(filePaths, contains(filePath));
+ });
+ }
+
+ test_watch_deleteFile() {
+ String filePath = posix.join(projPath, 'foo.dart');
+ // add root with a file
+ resourceProvider.newFile(filePath, 'contents');
+ manager.setRoots(<String>[projPath], <String>[]);
+ // the file was added
+ Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+ expect(filePaths, hasLength(1));
+ expect(filePaths, contains(filePath));
+ // delete the file
+ resourceProvider.deleteFile(filePath);
+ return pumpEventQueue().then((_) {
+ return expect(filePaths, hasLength(0));
+ });
+ }
+
+ test_watch_modifyFile() {
+ String filePath = posix.join(projPath, 'foo.dart');
+ // add root with a file
+ resourceProvider.newFile(filePath, 'contents');
+ manager.setRoots(<String>[projPath], <String>[]);
+ // the file was added
+ Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+ expect(filePaths, hasLength(1));
+ expect(filePaths, contains(filePath));
+ expect(filePaths[filePath], equals(manager.now));
+ // update the file
+ manager.now++;
+ resourceProvider.modifyFile(filePath, 'new contents');
+ return pumpEventQueue().then((_) {
+ return expect(filePaths[filePath], equals(manager.now));
+ });
+ }
+
+ test_watch_modifyPackageMapDependency() {
+ // create a dependency file
+ String dependencyPath = posix.join(projPath, 'dep');
+ resourceProvider.newFile(dependencyPath, 'contents');
+ packageMapProvider.dependencies.add(dependencyPath);
+ // create a Dart file
+ String dartFilePath = posix.join(projPath, 'main.dart');
+ resourceProvider.newFile(dartFilePath, 'contents');
+ // the created context has the expected empty package map
+ manager.setRoots(<String>[projPath], <String>[]);
+ expect(manager.currentContextPackageMaps[projPath], isEmpty);
+ // configure package map
+ String packagePath = '/package/foo';
+ resourceProvider.newFolder(packagePath);
+ packageMapProvider.packageMap = {
+ 'foo': projPath
+ };
+ // Changing a .dart file in the project shouldn't cause a new
+ // package map to be picked up.
+ resourceProvider.modifyFile(dartFilePath, 'new contents');
+ return pumpEventQueue().then((_) {
+ expect(manager.currentContextPackageMaps[projPath], isEmpty);
+ // However, changing the package map dependency should.
+ resourceProvider.modifyFile(dependencyPath, 'new contents');
+ return pumpEventQueue().then((_) {
+ expect(
+ manager.currentContextPackageMaps[projPath],
+ equals(packageMapProvider.packageMap));
+ });
+ });
+ }
+
+ test_watch_modifyPackageMapDependency_fail() {
+ // create a dependency file
+ String dependencyPath = posix.join(projPath, 'dep');
+ resourceProvider.newFile(dependencyPath, 'contents');
+ packageMapProvider.dependencies.add(dependencyPath);
+ // create a Dart file
+ String dartFilePath = posix.join(projPath, 'main.dart');
+ resourceProvider.newFile(dartFilePath, 'contents');
+ // the created context has the expected empty package map
+ manager.setRoots(<String>[projPath], <String>[]);
+ expect(manager.currentContextPackageMaps[projPath], isEmpty);
+ // Change the package map dependency so that the packageMapProvider is
+ // re-run, and arrange for it to return null from computePackageMap().
+ packageMapProvider.packageMap = null;
+ resourceProvider.modifyFile(dependencyPath, 'new contents');
+ return pumpEventQueue().then((_) {
+ // The package map should have been changed to null.
+ expect(manager.currentContextPackageMaps[projPath], isNull);
+ });
+ }
+}
+
+class TestContextDirectoryManager extends ContextDirectoryManager {
/**
* Source of timestamps stored in [currentContextFilePaths].
*/
@@ -27,16 +294,21 @@ class TestContextDirectoryManager extends ContextDirectoryManager {
final Set<String> currentContextPaths = new Set<String>();
/**
- * Map from context to (map from file path to timestamp of last event)
+ * Map from context to (map from file path to timestamp of last event).
*/
- final Map<String, Map<String, int>> currentContextFilePaths = <String, Map<String, int>>{};
+ final Map<String, Map<String, int>> currentContextFilePaths = <String,
+ Map<String, int>>{};
/**
- * Map from context to package map
+ * Map from context to package map.
*/
final Map<String, Map<String, List<Folder>>> currentContextPackageMaps =
<String, Map<String, List<Folder>>>{};
+ TestContextDirectoryManager(MemoryResourceProvider resourceProvider,
+ PackageMapProvider packageMapProvider)
+ : super(resourceProvider, packageMapProvider);
+
@override
void addContext(Folder folder, Map<String, List<Folder>> packageMap) {
String path = folder.path;
@@ -71,256 +343,8 @@ class TestContextDirectoryManager extends ContextDirectoryManager {
}
@override
- void updateContextPackageMap(Folder contextFolder,
- Map<String, List<Folder>> packageMap) {
- currentContextPackageMaps[contextFolder.path]= packageMap;
+ void updateContextPackageMap(Folder contextFolder, Map<String,
+ List<Folder>> packageMap) {
+ currentContextPackageMaps[contextFolder.path] = packageMap;
}
}
-
-main() {
- groupSep = ' | ';
-
- group('ContextDirectoryManager', () {
- TestContextDirectoryManager manager;
- MemoryResourceProvider resourceProvider;
- MockPackageMapProvider packageMapProvider;
-
- setUp(() {
- resourceProvider = new MemoryResourceProvider();
- packageMapProvider = new MockPackageMapProvider();
- manager = new TestContextDirectoryManager(resourceProvider, packageMapProvider);
- });
-
- test('add folder with pubspec', () {
- String projPath = '/my/proj';
- String pubspecPath = posix.join(projPath, 'pubspec.yaml');
- resourceProvider.newFolder(projPath);
- resourceProvider.newFile(pubspecPath, 'pubspec');
- manager.setRoots(<String>[projPath], <String>[]);
- expect(manager.currentContextPaths, hasLength(1));
- expect(manager.currentContextPaths, contains(projPath));
- expect(manager.currentContextFilePaths[projPath], hasLength(0));
- });
-
- test('newly added folders get proper package map', () {
- String projPath = '/my/proj';
- String packagePath = '/package/foo';
- resourceProvider.newFolder(projPath);
- Folder packageFolder = resourceProvider.newFolder(packagePath);
- packageMapProvider.packageMap = {'foo': [packageFolder]};
- manager.setRoots(<String>[projPath], <String>[]);
- expect(manager.currentContextPackageMaps[projPath],
- equals(packageMapProvider.packageMap));
- });
-
- test('add folder without pubspec', () {
- String projPath = '/my/proj';
- resourceProvider.newFolder(projPath);
- packageMapProvider.packageMap = null;
- manager.setRoots(<String>[projPath], <String>[]);
- expect(manager.currentContextPaths, hasLength(1));
- expect(manager.currentContextPaths, contains(projPath));
- expect(manager.currentContextFilePaths[projPath], hasLength(0));
- });
-
- test('add folder with dart file', () {
- String projPath = '/my/proj';
- resourceProvider.newFolder(projPath);
- String filePath = posix.join(projPath, 'foo.dart');
- resourceProvider.newFile(filePath, 'contents');
- manager.setRoots(<String>[projPath], <String>[]);
- var filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, hasLength(1));
- expect(filePaths, contains(filePath));
- });
-
- test('add folder with dummy link', () {
- String projPath = '/my/proj';
- resourceProvider.newFolder(projPath);
- String filePath = posix.join(projPath, 'foo.dart');
- resourceProvider.newDummyLink(filePath);
- manager.setRoots(<String>[projPath], <String>[]);
- var filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, isEmpty);
- });
-
- test('add folder with dart file in subdir', () {
- String projPath = '/my/proj';
- resourceProvider.newFolder(projPath);
- String filePath = posix.join(projPath, 'foo', 'bar.dart');
- resourceProvider.newFile(filePath, 'contents');
- manager.setRoots(<String>[projPath], <String>[]);
- var filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, hasLength(1));
- expect(filePaths, contains(filePath));
- });
-
- test('remove folder with pubspec', () {
- String projPath = '/my/proj';
- String pubspecPath = posix.join(projPath, 'pubspec.yaml');
- resourceProvider.newFolder(projPath);
- resourceProvider.newFile(pubspecPath, 'pubspec');
- manager.setRoots(<String>[projPath], <String>[]);
- manager.setRoots(<String>[], <String>[]);
- expect(manager.currentContextPaths, hasLength(0));
- expect(manager.currentContextFilePaths, hasLength(0));
- });
-
- test('remove folder without pubspec', () {
- String projPath = '/my/proj';
- resourceProvider.newFolder(projPath);
- packageMapProvider.packageMap = null;
- manager.setRoots(<String>[projPath], <String>[]);
- manager.setRoots(<String>[], <String>[]);
- expect(manager.currentContextPaths, hasLength(0));
- expect(manager.currentContextFilePaths, hasLength(0));
- });
-
- test('ignore files in packages dir', () {
- String projPath = '/my/proj';
- resourceProvider.newFolder(projPath);
- String pubspecPath = posix.join(projPath, 'pubspec.yaml');
- resourceProvider.newFile(pubspecPath, 'pubspec');
- String filePath1 = posix.join(projPath, 'packages', 'file1.dart');
- resourceProvider.newFile(filePath1, 'contents');
- manager.setRoots(<String>[projPath], <String>[]);
- Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, hasLength(0));
- String filePath2 = posix.join(projPath, 'packages', 'file2.dart');
- resourceProvider.newFile(filePath2, 'contents');
- return pumpEventQueue().then((_) {
- expect(filePaths, hasLength(0));
- });
- });
-
- group('isInAnalysisRoot', () {
- test('in root', () {
- String projPath = '/project';
- resourceProvider.newFolder(projPath);
- manager.setRoots(<String>[projPath], <String>[]);
- expect(manager.isInAnalysisRoot('/project/test.dart'), isTrue);
- });
-
- test('not in root', () {
- String projPath = '/project';
- resourceProvider.newFolder(projPath);
- manager.setRoots(<String>[projPath], <String>[]);
- expect(manager.isInAnalysisRoot('/test.dart'), isFalse);
- });
- });
-
- group('detect context modifications', () {
- String projPath;
-
- setUp(() {
- projPath = '/my/proj';
- resourceProvider.newFolder(projPath);
- });
-
- test('Add dummy link', () {
- manager.setRoots(<String>[projPath], <String>[]);
- Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, isEmpty);
- String filePath = posix.join(projPath, 'foo.dart');
- resourceProvider.newDummyLink(filePath);
- return pumpEventQueue().then((_) {
- expect(filePaths, isEmpty);
- });
- });
-
- test('Add file', () {
- manager.setRoots(<String>[projPath], <String>[]);
- Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, hasLength(0));
- String filePath = posix.join(projPath, 'foo.dart');
- resourceProvider.newFile(filePath, 'contents');
- return pumpEventQueue().then((_) {
- expect(filePaths, hasLength(1));
- expect(filePaths, contains(filePath));
- });
- });
-
- test('Add file in subdirectory', () {
- manager.setRoots(<String>[projPath], <String>[]);
- Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, hasLength(0));
- String filePath = posix.join(projPath, 'foo', 'bar.dart');
- resourceProvider.newFile(filePath, 'contents');
- return pumpEventQueue().then((_) {
- expect(filePaths, hasLength(1));
- expect(filePaths, contains(filePath));
- });
- });
-
- test('Delete file', () {
- String filePath = posix.join(projPath, 'foo.dart');
- resourceProvider.newFile(filePath, 'contents');
- manager.setRoots(<String>[projPath], <String>[]);
- Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, hasLength(1));
- expect(filePaths, contains(filePath));
- resourceProvider.deleteFile(filePath);
- return pumpEventQueue().then((_) => expect(filePaths, hasLength(0)));
- });
-
- test('Modify file', () {
- String filePath = posix.join(projPath, 'foo.dart');
- resourceProvider.newFile(filePath, 'contents');
- manager.setRoots(<String>[projPath], <String>[]);
- Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
- expect(filePaths, hasLength(1));
- expect(filePaths, contains(filePath));
- expect(filePaths[filePath], equals(manager.now));
- manager.now++;
- resourceProvider.modifyFile(filePath, 'new contents');
- return pumpEventQueue().then((_) => expect(filePaths[filePath], equals(
- manager.now)));
- });
-
- test('Modify package map dependency', () {
- String dependencyPath = posix.join(projPath, 'dep');
- resourceProvider.newFile(dependencyPath, 'contents');
- String dartFilePath = posix.join(projPath, 'main.dart');
- resourceProvider.newFile(dartFilePath, 'contents');
- packageMapProvider.dependencies.add(dependencyPath);
- manager.setRoots(<String>[projPath], <String>[]);
- expect(manager.currentContextPackageMaps[projPath],
- equals(packageMapProvider.packageMap));
- String packagePath = '/package/foo';
- resourceProvider.newFolder(packagePath);
- packageMapProvider.packageMap = {'foo': projPath};
- // Changing a .dart file in the project shouldn't cause a new
- // package map to be picked up.
- resourceProvider.modifyFile(dartFilePath, 'new contents');
- return pumpEventQueue().then((_) {
- expect(manager.currentContextPackageMaps[projPath], isEmpty);
- // However, changing the package map dependency should.
- resourceProvider.modifyFile(dependencyPath, 'new contents');
- return pumpEventQueue().then((_) {
- expect(manager.currentContextPackageMaps[projPath],
- equals(packageMapProvider.packageMap));
- });
- });
- });
-
- test('Modify package map dependency - packageMapProvider failure', () {
- String dependencyPath = posix.join(projPath, 'dep');
- resourceProvider.newFile(dependencyPath, 'contents');
- String dartFilePath = posix.join(projPath, 'main.dart');
- resourceProvider.newFile(dartFilePath, 'contents');
- packageMapProvider.dependencies.add(dependencyPath);
- manager.setRoots(<String>[projPath], <String>[]);
- expect(manager.currentContextPackageMaps[projPath],
- equals(packageMapProvider.packageMap));
- // Change the package map dependency so that the packageMapProvider is
- // re-run, and arrange for it to return null from computePackageMap().
- packageMapProvider.packageMap = null;
- resourceProvider.modifyFile(dependencyPath, 'new contents');
- return pumpEventQueue().then((_) {
- // The package map should have been changed to null.
- expect(manager.currentContextPackageMaps[projPath], isNull);
- });
- });
- });
- });
-}
« no previous file with comments | « pkg/analysis_server/lib/src/context_directory_manager.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698