Up today I hope to figure out how to test a "real" Dart application. I have been using the
unittest library to test some of the client-side code that I built to support Dart for Hipsters, but the code in question was not laid out to use packages from Dart Pub. That is, the code was placed directly in public/scripts rather than in public/scripts/web. Furthermore, I have not needed to account for pub packages in my tests so far—it all existed directly in public/scripts.The code layout, including tests, that I now have in my sample app looks like:
.
├── packages
│ ├── dirty -> /home/chris/.pub-cache/hosted/pub.dartlang.org/dirty-0.0.2/lib
│ ├── unittest -> /home/chris/.pub-cache/hosted/pub.dartlang.org/unittest-0.2.8+2/lib
│ └── uuid -> /home/chris/.pub-cache/hosted/pub.dartlang.org/uuid-0.0.9/lib
├── public
│ ├── images
│ ├── index.html
│ ├── scripts
│ │ ├── packages
│ │ │ └── hipster_mvc -> /home/chris/.pub-cache/hosted/pub.dartlang.org/hipster_mvc-0.2.0/lib
│ │ ├── pubspec.lock
│ │ ├── pubspec.yaml
│ │ └── web
│ │ ├── Collections.Comics.dart
│ │ ├── main.dart
│ │ ├── Models.ComicBook.dart
│ │ ├── packages -> /home/chris/repos/dart-comics/public/scripts/packages
│ │ ├── Views.AddComicForm.dart
│ │ └── Views.Comics.dart
│ └── stylesheets
├── pubspec.yaml
└── test
├── HipsterCollectionTest.dart
├── index.html
├── packages -> /home/chris/repos/dart-comics/packages
└── Views.AddComicForm_test.dartI had been placing my client-side tests in the root-level test directory. Now that my client-side Dart code resides in public/scripts/web instead of public/scripts and, more importantly, now that the Hipster MVC classes are in the Pub's packages directory, the root level test directory will no longer work. I get errors like the following:Failed to load a file file:///home/chris/repos/dart-comics/test/packages/hipster_mvc/hipster_view.dart Views.AddComicForm_test.dart:-1 GET file:///home/chris/repos/dart-comics/test/packages/hipster_mvc/hipster_view.dart index.html:17The problem is in the
Views.AddComicForm.dart file:library add_comic_form_view;
import 'dart:html';
import 'package:hipster_mvc/hipster_view.dart';
class AddComicForm extends HipsterView {
// ...
}The import of the hipster_view.dart library is looking in the top-level packages directory since the test resides in the top-level test directory. But the only packages that reside in the top-level packages directory are those that support the Dart web server.I had resisted placing my tests in the
public/test directory because then they would be in the public (i.e. publicly available) directory. But now it seem that I may not have a choice.So, in the
public/scripts directory, I add a test sub-directory and run pub install:➜ scripts git:(master) ✗ mkdir test ➜ scripts git:(master) ✗ pub install Resolving dependencies... Dependencies installed! ➜ scripts git:(master) ✗ ls -l test total 0 lrwxrwxrwx 1 chris chris 53 Dec 14 23:15 packages -> /home/chris/repos/dart-comics/public/scripts/packagesThis creates a link to the pub packages directory, so I seem to be on the right track.
I move my client-side tests from the root level into this new public test directory and adjust the import paths accordingly:
import 'package:unittest/unittest.dart';
import 'package:unittest/html_enhanced_config.dart';
import '../web/Views.AddComicForm.dart';
main() {
// ...
}With that, I have my tests passing again, now from the public directory:I suppose the test code in the public directory is not a huge deal. Still it seems wrong to allow test code to be publicly available from the web server. I could use something like an .htacess file to prevent access to the test sub-directory, but that too seems less than ideal.
Instead, I move my application code, my tests and the associated
pubspec.yaml file outside of public. For now, I place it all in a new directory named appcode in the application root. After re-running pub install, the appcode sub-directory looks like the following:➜ appcode git:(master) ✗ tree
.
├── packages
│ ├── hipster_mvc -> /home/chris/.pub-cache/hosted/pub.dartlang.org/hipster_mvc-0.2.0/lib
│ └── unittest -> /home/chris/.pub-cache/hosted/pub.dartlang.org/unittest-0.2.8+2/lib
├── pubspec.lock
├── pubspec.yaml
├── test
│ ├── HipsterCollectionTest.dart
│ ├── index.html
│ ├── packages -> /home/chris/repos/dart-comics/appcode/packages
│ └── Views.AddComicForm_test.dart
└── web
├── Collections.Comics.dart
├── main.dart
├── ModalDialog.dart
├── Models.ComicBook.dart
├── packages -> /home/chris/repos/dart-comics/appcode/packages
├── Views.AddComic.dart
├── Views.AddComicForm.dart
└── Views.Comics.dartThe trick here is that, publicly, I only need the stuff in the web sub-directory. Well, I also need the pub packages, but I have them in the web sub-directory by virtue of the packages symlink that points to an absolute path. In other words, I can symlink just the web sub-directory into public:➜ appcode git:(master) ✗ pwd /home/chris/repos/dart-comics/appcode ➜ appcode git:(master) ✗ cd ../public/scripts ➜ scripts git:(master) ✗ ln -s ../../appcode/web dart_comicsAnd that works. I still have my test suite passing, but now it is only accessible from a local filesystem. And, I still have my application working:
After considering it for a bit, I believe that this (or something like this) is what Dart Pub wants me to do. That is, I believe that including only the web sub-directory in a public folder is how Dart applications should be served up. The web sub-directory could come from an
appcode sub-directory as I have done here. More interestingly, it could come a pub package—possibly from a git repository.I think that is an idea worth pursuing a bit more. Tomorrow.
Day #599


No comments:
Post a Comment