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