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