| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /// Unit tests for doc. | |
| 6 library dartdocTests; | |
| 7 | |
| 8 import 'dart:async'; | |
| 9 import 'dart:io'; | |
| 10 | |
| 11 import 'package:path/path.dart' as path; | |
| 12 import 'package:unittest/unittest.dart'; | |
| 13 | |
| 14 // TODO(rnystrom): Use "package:" URL (#4968). | |
| 15 import '../lib/dartdoc.dart' as dd; | |
| 16 import '../lib/markdown.dart'; | |
| 17 import 'markdown_test.dart'; | |
| 18 | |
| 19 main() { | |
| 20 // Some tests take more than the default 20 second unittest timeout. | |
| 21 unittestConfiguration.timeout = null; | |
| 22 group('isAbsolute', () { | |
| 23 final doc = new dd.Dartdoc(); | |
| 24 | |
| 25 test('returns false if there is no scheme', () { | |
| 26 expect(doc.isAbsolute('index.html'), isFalse); | |
| 27 expect(doc.isAbsolute('foo/index.html'), isFalse); | |
| 28 expect(doc.isAbsolute('foo/bar/index.html'), isFalse); | |
| 29 }); | |
| 30 | |
| 31 test('returns true if there is a scheme', () { | |
| 32 expect(doc.isAbsolute('http://google.com'), isTrue); | |
| 33 expect(doc.isAbsolute('hTtPs://google.com'), isTrue); | |
| 34 expect(doc.isAbsolute('mailto:fake@email.com'), isTrue); | |
| 35 }); | |
| 36 }); | |
| 37 | |
| 38 group('relativePath', () { | |
| 39 final doc = new dd.Dartdoc(); | |
| 40 | |
| 41 test('absolute path is unchanged', () { | |
| 42 doc.startFile('dir/sub/file.html'); | |
| 43 expect(doc.relativePath('http://foo.com'), equals('http://foo.com')); | |
| 44 }); | |
| 45 | |
| 46 test('from root to root', () { | |
| 47 doc.startFile('root.html'); | |
| 48 expect(doc.relativePath('other.html'), equals('other.html')); | |
| 49 }); | |
| 50 | |
| 51 test('from root to directory', () { | |
| 52 doc.startFile('root.html'); | |
| 53 expect(doc.relativePath('dir/file.html'), equals('dir/file.html')); | |
| 54 }); | |
| 55 | |
| 56 test('from root to nested', () { | |
| 57 doc.startFile('root.html'); | |
| 58 expect(doc.relativePath('dir/sub/file.html'), equals( | |
| 59 'dir/sub/file.html')); | |
| 60 }); | |
| 61 | |
| 62 test('from directory to root', () { | |
| 63 doc.startFile('dir/file.html'); | |
| 64 expect(doc.relativePath('root.html'), equals('../root.html')); | |
| 65 }); | |
| 66 | |
| 67 test('from nested to root', () { | |
| 68 doc.startFile('dir/sub/file.html'); | |
| 69 expect(doc.relativePath('root.html'), equals('../../root.html')); | |
| 70 }); | |
| 71 | |
| 72 test('from dir to dir with different path', () { | |
| 73 doc.startFile('dir/file.html'); | |
| 74 expect(doc.relativePath('other/file.html'), equals('../other/file.html')); | |
| 75 }); | |
| 76 | |
| 77 test('from nested to nested with different path', () { | |
| 78 doc.startFile('dir/sub/file.html'); | |
| 79 expect(doc.relativePath('other/sub/file.html'), equals( | |
| 80 '../../other/sub/file.html')); | |
| 81 }); | |
| 82 | |
| 83 test('from nested to directory with different path', () { | |
| 84 doc.startFile('dir/sub/file.html'); | |
| 85 expect(doc.relativePath('other/file.html'), equals( | |
| 86 '../../other/file.html')); | |
| 87 }); | |
| 88 }); | |
| 89 | |
| 90 group('dartdoc markdown', () { | |
| 91 group('[::] blocks', () { | |
| 92 | |
| 93 validateDartdocMarkdown('simple case', ''' | |
| 94 before [:source:] after | |
| 95 ''', ''' | |
| 96 <p>before <code>source</code> after</p> | |
| 97 '''); | |
| 98 | |
| 99 validateDartdocMarkdown('unmatched [:', ''' | |
| 100 before [: after | |
| 101 ''', ''' | |
| 102 <p>before [: after</p> | |
| 103 '''); | |
| 104 validateDartdocMarkdown('multiple spans in one text', ''' | |
| 105 a [:one:] b [:two:] c | |
| 106 ''', ''' | |
| 107 <p>a <code>one</code> b <code>two</code> c</p> | |
| 108 '''); | |
| 109 | |
| 110 validateDartdocMarkdown('multi-line', ''' | |
| 111 before [:first | |
| 112 second:] after | |
| 113 ''', ''' | |
| 114 <p>before <code>first | |
| 115 second</code> after</p> | |
| 116 '''); | |
| 117 | |
| 118 validateDartdocMarkdown('contain backticks', ''' | |
| 119 before [:can `contain` backticks:] after | |
| 120 ''', ''' | |
| 121 <p>before <code>can `contain` backticks</code> after</p> | |
| 122 '''); | |
| 123 | |
| 124 validateDartdocMarkdown('contain double backticks', ''' | |
| 125 before [:can ``contain`` backticks:] after | |
| 126 ''', ''' | |
| 127 <p>before <code>can ``contain`` backticks</code> after</p> | |
| 128 '''); | |
| 129 | |
| 130 validateDartdocMarkdown('contain backticks with spaces', ''' | |
| 131 before [: `tick` :] after | |
| 132 ''', ''' | |
| 133 <p>before <code>`tick`</code> after</p> | |
| 134 '''); | |
| 135 | |
| 136 validateDartdocMarkdown('multiline with spaces', ''' | |
| 137 before [:in `tick` | |
| 138 another:] after | |
| 139 ''', ''' | |
| 140 <p>before <code>in `tick` | |
| 141 another</code> after</p> | |
| 142 '''); | |
| 143 | |
| 144 validateDartdocMarkdown('ignore markup inside code', ''' | |
| 145 before [:*b* _c_:] after | |
| 146 ''', ''' | |
| 147 <p>before <code>*b* _c_</code> after</p> | |
| 148 '''); | |
| 149 | |
| 150 validateDartdocMarkdown('escape HTML characters', ''' | |
| 151 [:<&>:] | |
| 152 ''', ''' | |
| 153 <p><code><&></code></p> | |
| 154 '''); | |
| 155 | |
| 156 validateDartdocMarkdown('escape HTML tags', ''' | |
| 157 '*' [:<em>:] | |
| 158 ''', ''' | |
| 159 <p>'*' <code><em></code></p> | |
| 160 '''); | |
| 161 }); | |
| 162 }); | |
| 163 | |
| 164 group('integration tests', () { | |
| 165 test('no entrypoints', () { | |
| 166 _testRunDartDoc([], (result) { | |
| 167 expect(result.exitCode, 1); | |
| 168 }); | |
| 169 }); | |
| 170 | |
| 171 test('entrypoint in lib', () { | |
| 172 _testRunDartDoc(['test_files/lib/no_package_test_file.dart'], (result) { | |
| 173 expect(result.exitCode, 0); | |
| 174 _expectDocumented(result.stdout, libCount: 1, typeCount: 1, memberCount:
0); | |
| 175 }); | |
| 176 }); | |
| 177 | |
| 178 test('entrypoint somewhere with packages locally', () { | |
| 179 _testRunDartDoc(['test_files/package_test_file.dart'], (result) { | |
| 180 expect(result.exitCode, 0); | |
| 181 _expectDocumented(result.stdout, libCount: 1, typeCount: 1, memberCount:
0); | |
| 182 }); | |
| 183 }); | |
| 184 | |
| 185 test('file does not exist', () { | |
| 186 _testRunDartDoc(['test_files/this_file_does_not_exist.dart'], (result) { | |
| 187 expect(result.exitCode, 1); | |
| 188 }); | |
| 189 }); | |
| 190 }); | |
| 191 } | |
| 192 | |
| 193 void _testRunDartDoc(List<String> libraryPaths, void eval(ProcessResult)) { | |
| 194 expect(_runDartdoc(libraryPaths).then(eval), completes); | |
| 195 } | |
| 196 | |
| 197 /// The path to the root directory of the dartdoc entrypoint. | |
| 198 String get _dartdocDir { | |
| 199 var dir = path.absolute(Platform.script.toFilePath()); | |
| 200 while (path.basename(dir) != 'dartdoc') { | |
| 201 if (!path.absolute(dir).contains('dartdoc') || dir == path.dirname(dir)) { | |
| 202 fail('Unable to find root dartdoc directory.'); | |
| 203 } | |
| 204 dir = path.dirname(dir); | |
| 205 } | |
| 206 return path.absolute(dir); | |
| 207 } | |
| 208 | |
| 209 /// The path to use for the package root for subprocesses. | |
| 210 String get _packageRoot { | |
| 211 var sdkVersionPath = path.join(_dartdocDir, '..', '..', '..', 'version'); | |
| 212 if (new File(sdkVersionPath).existsSync()) { | |
| 213 // It looks like dartdoc is being run from the SDK, so we should set the | |
| 214 // package root to the SDK's packages directory. | |
| 215 return path.absolute(path.join(_dartdocDir, '..', '..', '..', 'packages')); | |
| 216 } | |
| 217 | |
| 218 // It looks like Dartdoc is being run from the Dart repo, so the package root | |
| 219 // is in the build output directory. We can find that directory relative to | |
| 220 // the Dart executable, but that could be in one of two places: in | |
| 221 // "$BUILD/dart" or "$BUILD/dart-sdk/bin/dart". | |
| 222 var executableDir = path.dirname(Platform.executable); | |
| 223 if (new Directory(path.join(executableDir, 'dart-sdk')).existsSync()) { | |
| 224 // The executable is in "$BUILD/dart". | |
| 225 return path.absolute(path.join(executableDir, 'packages')); | |
| 226 } else { | |
| 227 // The executable is in "$BUILD/dart-sdk/bin/dart". | |
| 228 return path.absolute(path.join(executableDir, '..', '..', 'packages')); | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 /// Runs dartdoc with the libraryPaths provided, and completes to dartdoc's | |
| 233 /// ProcessResult. | |
| 234 Future<ProcessResult> _runDartdoc(List<String> libraryPaths) { | |
| 235 var dartBin = Platform.executable; | |
| 236 | |
| 237 var dartdoc = path.join(_dartdocDir, 'bin/dartdoc.dart'); | |
| 238 | |
| 239 final runArgs = ['--package-root=$_packageRoot/', dartdoc]; | |
| 240 | |
| 241 // Turn relative libraryPaths to absolute ones. | |
| 242 runArgs.addAll(libraryPaths | |
| 243 .map((e) => path.join(path.absolute(dd.scriptDir), e))); | |
| 244 | |
| 245 return Process.run(dartBin, runArgs); | |
| 246 } | |
| 247 | |
| 248 final _dartdocCompletionRegExp = | |
| 249 new RegExp(r'Documentation complete -- documented (\d+) libraries, (\d+) types
, and (\d+) members\.'); | |
| 250 | |
| 251 void _expectDocumented(String output, { int libCount, int typeCount, | |
| 252 int memberCount}) { | |
| 253 | |
| 254 final completionMatches = _dartdocCompletionRegExp.allMatches(output) | |
| 255 .toList(); | |
| 256 | |
| 257 expect(completionMatches, hasLength(1), | |
| 258 reason: 'dartdoc output should contain one summary'); | |
| 259 | |
| 260 final completionMatch = completionMatches.single; | |
| 261 | |
| 262 if(libCount != null) { | |
| 263 expect(int.parse(completionMatch[1]), libCount, | |
| 264 reason: 'expected library count'); | |
| 265 } | |
| 266 | |
| 267 if(typeCount != null) { | |
| 268 expect(int.parse(completionMatch[2]), typeCount, | |
| 269 reason: 'expected type count'); | |
| 270 } | |
| 271 | |
| 272 if(memberCount != null) { | |
| 273 expect(int.parse(completionMatch[3]), memberCount, | |
| 274 reason: 'expected member count'); | |
| 275 } | |
| 276 } | |
| 277 | |
| 278 | |
| 279 validateDartdocMarkdown(String description, String markdown, | |
| 280 String html) { | |
| 281 var dartdoc = new dd.Dartdoc(); | |
| 282 validate(description, markdown, html, linkResolver: dartdoc.dartdocResolver, | |
| 283 inlineSyntaxes: dartdoc.dartdocSyntaxes); | |
| 284 } | |
| OLD | NEW |