While updating my Hipster MVC library, I found that the old style of
dartdoc
documentation no longer worked. The dartdoc
tool is part of the Dart SDK. It parses source code as Markdown, producing very pretty documentation.The problem is that documentation marked with triple slashes was not formatted correctly. The following commented Dart code is not producing properly formatted documentation:
/// Testing /// var testing = 'this is source code'; get foo => 'bar';The most obvious problem is that code samples, introduced by four spaces, are not being formatted as code samples.
After a bit of investigation, I found that the cause is the
CommentMap
class improperly stripping newlines from triple-slashed comments. Given the above multi-line comment, the CommentMap
class was passing a single line to the markdown parser:Testing var testing = 'this is source code';Since it was a single line, markdown was not seeing the indented code line.
Anyhow, given the above precondition, I think that I want the following test for my
dartdoc
code fix:main() { test('triple slashed comments retain newlines', () { Commentmap cm = new CommentMap(); var comment = cm.find(new FakeSourceLocation()); expect(comment, equals("Testing\n var testing = 'this is source code';")); }); }In other words, I very much want that newline character in the
expect()
statement.In order for that test to work, I am going to need a bit more setup in
dart/sdk/lib/_internal/dartdoc/test/comment_map_test.dart
. I start with the license, which appears in all of the tests, the name of the library, and some imports:// Copyright (c) 2012, 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. /// Unit tests for comment map. library commentMapTests; import 'dart:uri'; import '../lib/mirrors.dart'; import '../../compiler/implementation/scanner/scannerlib.dart' as dart2js;The imports are taken from the other libraries in the
dartdoc
test suite, though I do apply some process of elimination to figure out which ones really need to be included.Next, I need to import the unittest library. Again, I copy the import from other dartdoc tests, comment and all:
// TODO(rnystrom): Better path to unittest. import '../../../../../pkg/unittest/lib/unittest.dart';Before submitting a patch back to the Dart maintainers I need to modify that path as I found yesterday.
Finally, I need to pull in the
CommentMap
class. It is "part" of the dartdoc
library (as opposed to a separate library that needs to be imported). So I need to pull it into my test with the part
keyword:// TODO(rnystrom): Use "package:" URL (#4968). part '../lib/src/dartdoc/comment_map.dart';Once more, I copy comments from similar statements to (hopefully) increase the likelihood that my patch will be accepted.
The last thing that I need to do is define the
FakeSourceLocation
class that will be used by the CommentMap
. Reading through the CommentMap
code, the source location object needs to define the sourceUri
, offset
, and sourceText
properties. For this fake/test class, I define them as:class FakeSourceLocation implements SourceLocation { Uri get sourceUri => new Uri('file:///tmp/test.dart'); int get offset => 57; String get sourceText => """ /// Testing /// var testing = 'this is source code'; get foo => 'bar'; """; }The
sourceUri
and sourceText
are pretty straight-forward. The offset
is the number of characters from the start of the string under the source code. In this case, there are 57 characters of comments before the foo
getter is reached.With that, I have my failing test:
➜ dart-sdk git:(master) ✗ ./dart/tools/testing/bin/linux/dart \ ./dart/sdk/lib/_internal/dartdoc/test/comment_map_test.dart unittest-suite-wait-for-done FAIL: triple slashed comments retain newlines Expected: 'Testing\n var testing = 'this is source code';' but: was 'Testing var testing = 'this is source code';'. #0 DefaultFailureHandler.fail (file:///home/chris/repos/dart-sdk/dart/pkg/unittest/lib/src/expect.dart:86:5) #1 DefaultFailureHandler.failMatch (file:///home/chris/repos/dart-sdk/dart/pkg/unittest/lib/src/expect.dart:90:9) #2 expect (file:///home/chris/repos/dart-sdk/dart/pkg/unittest/lib/src/expect.dart:55:29) #3 main.As expected, my test fails because the mapped comment no longer includes the newline. Without that newline, subsequent markdown processing will not produce the desired, pretty output.(file:///home/chris/repos/dart-sdk/dart/sdk/lib/_internal/dartdoc/test/comment_map_test.dart:33:11) #4 TestCase.run (file:///home/chris/repos/dart-sdk/dart/pkg/unittest/lib/src/test_case.dart:83:11) #5 _nextBatch._nextBatch. (file:///home/chris/repos/dart-sdk/dart/pkg/unittest/lib/unittest.dart:803:19) #6 guardAsync (file:///home/chris/repos/dart-sdk/dart/pkg/unittest/lib/unittest.dart:762:19) 0 PASSED, 1 FAILED, 0 ERRORS
Happily, the fix is easy. I just need to re-add a newline character when building up the triple-slashed comments in
CommentMap
: _parseComments(Source source) {
// ...
while (token.kind != dart2js.EOF_TOKEN) {
if (token.kind == dart2js.COMMENT_TOKEN) {
// ...
} else if (text.startsWith('///')) {
var line = text.substring(3);
// Allow a leading space.
if (line.startsWith(' ')) line = line.substring(1);
if (lastComment == null) {
lastComment = line;
} else {
lastComment = "$lastComment\n$line";
}
}
} else if (token.kind == dart2js.HASH_TOKEN) {
// ...
}
}
With the assembled comments for triple-slashes again including a newline, I have a passing test:➜ dart-sdk git:(master) ✗ ./dart/tools/testing/bin/linux/dart \ ./dart/sdk/lib/_internal/dartdoc/test/comment_map_test.dart unittest-suite-wait-for-done PASS: triple slashed comments retain newlines All 1 tests passed. unittest-suite-successWith that, I feel more confident in submitting a fix. Tomorrow.
Day #561
No comments:
Post a Comment