From e8d0e178035064a30e4e58ba7605f0ca33f575cd Mon Sep 17 00:00:00 2001 From: Istvan Soos Date: Thu, 25 May 2017 16:49:31 +0200 Subject: [PATCH] Modular analyzer, added end2end test. --- bin/main.dart | 4 +- lib/pana.dart | 260 +++++------------- lib/src/pub_summary.dart | 32 +-- lib/src/sdk_env.dart | 169 ++++++++++++ lib/src/utils.dart | 70 +++++ test/end2end/pub_server-0.1.1+3.json | 167 +++++++++++ test/end2end_test.dart | 39 +++ .../{pana_test.dart => pub_summary_test.dart} | 13 - test/utils_test.dart | 21 ++ 9 files changed, 539 insertions(+), 236 deletions(-) create mode 100644 lib/src/sdk_env.dart create mode 100644 lib/src/utils.dart create mode 100644 test/end2end/pub_server-0.1.1+3.json create mode 100644 test/end2end_test.dart rename test/{pana_test.dart => pub_summary_test.dart} (92%) create mode 100644 test/utils_test.dart diff --git a/bin/main.dart b/bin/main.dart index f1927cbd4..1580f4344 100644 --- a/bin/main.dart +++ b/bin/main.dart @@ -46,8 +46,8 @@ main(List arguments) async { try { try { - var summary = - await inspectPackage(pkg, version: version, pubCachePath: tempPath); + PackageAnalyzer analyzer = new PackageAnalyzer(pubCacheDir: tempPath); + var summary = await analyzer.inspectPackage(pkg, version: version); print(prettyJson(summary)); } catch (e, stack) { diff --git a/lib/pana.dart b/lib/pana.dart index e0f8c1f34..471405e01 100644 --- a/lib/pana.dart +++ b/lib/pana.dart @@ -6,219 +6,95 @@ import 'dart:collection'; import 'dart:convert'; import 'dart:io'; -import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; import 'src/analyzer_output.dart'; import 'src/logging.dart'; import 'src/pub_summary.dart'; +import 'src/sdk_env.dart'; import 'src/summary.dart'; +import 'src/utils.dart'; export 'src/pub_summary.dart'; export 'src/summary.dart'; +export 'src/utils.dart'; -String prettyJson(obj) => const JsonEncoder.withIndent(' ').convert(obj).trim(); +class PackageAnalyzer { + DartSdk _dartSdk; + PubEnvironment _pubEnv; -Future inspectPackage(String pkgName, - {String version, String pubCachePath}) async { - var versionResult = _handleErrors(await Process.run('dart', ['--version'])); - - var sdkVersion = versionResult.stderr.toString().trim(); - log.info("SDK: $sdkVersion"); + PackageAnalyzer({String sdkDir, String pubCacheDir}) { + _dartSdk = new DartSdk(sdkDir: sdkDir); + _pubEnv = new PubEnvironment(dartSdk: _dartSdk, pubCacheDir: pubCacheDir); + } - log.info("Package: $pkgName"); + Future inspectPackage(String package, {String version}) async { + var sdkVersion = await _dartSdk.version; + log.info("SDK: $sdkVersion"); - Version ver; - if (version != null) { - ver = new Version.parse(version); - log.info("Version: $ver"); - } + log.info("Package: $package"); - if (pubCachePath != null) { - log.info("Using .package-cache: ${pubCachePath}"); - var tempDir = new Directory(pubCachePath).resolveSymbolicLinksSync(); - if (tempDir != pubCachePath) { - throw new ArgumentError([ - "Make sure you resolve symlinks:", - pubCachePath, - tempDir - ].join('\n')); + Version ver; + if (version != null) { + ver = new Version.parse(version); + log.info("Version: $ver"); } - } - log.info("Downloading package..."); - var pkgDir = - await downloadPkg(pkgName, version: ver, pubCachePath: pubCachePath); - log.info("Package at ${pkgDir.path}"); - - log.info('Counting files...'); - var result = _handleErrors( - await Process.run('find', [pkgDir.path, '-name', '*.dart'])); - - var dartFiles = new SplayTreeSet.from( - LineSplitter.split(result.stdout).map((path) { - assert(p.isWithin(pkgDir.path, path)); - - return p.relative(path, from: pkgDir.path); - })); - - log.info("Checking formatting..."); - var unformattedFiles = - new SplayTreeSet.from(filesNeedingFormat(pkgDir.path)); - - log.info("Pub upgrade..."); - var summary = await pubUpgrade(pkgDir.path, pubCachePath: pubCachePath); - log.info("Package version: ${summary.pkgVersion}"); - - Set analyzerItems; - try { - analyzerItems = await pkgAnalyze(pkgDir.path); - } on ArgumentError catch (e) { - if (e.toString().contains("No dart files found at: .")) { - log.warning("No files to analyze..."); - analyzerItems = new Set(); - } else { - rethrow; + if (_pubEnv.pubCacheDir != null) { + log.info("Using .package-cache: ${_pubEnv.pubCacheDir}"); } - } - - return new Summary(sdkVersion, pkgName, pkgDir.version, dartFiles, summary, - analyzerItems, unformattedFiles); -} - -List filesNeedingFormat(String pkgPath) { - var result = Process - .runSync('dartfmt', ['--dry-run', '--set-exit-if-changed', pkgPath]); - - if (result.exitCode == 0) { - return const []; - } - - var lines = LineSplitter.split(result.stdout).toList()..sort(); - - assert(lines.isNotEmpty); - - return lines; -} - -Future> pkgAnalyze(String pkgPath) async { - log.info('Running `dartanalyzer`...'); - var proc = await Process.run( - 'dartanalyzer', ['--strong', '--format', 'machine', '.'], - workingDirectory: pkgPath); - - try { - return new SplayTreeSet.from(LineSplitter - .split(proc.stderr) - .map((s) => AnalyzerOutput.parse(s, projectDir: pkgPath)) - .where((e) => e != null)); - } on ArgumentError { - // TODO: we should figure out a way to succeed here, right? - // Or at least do partial results and not blow up - log.severe("Bad input?"); - log.severe(proc.stderr); - rethrow; - } -} - -Future pubUpgrade(String pkgPath, {String pubCachePath}) async { - var pubEnv = new Map.from(_pubEnv); - if (pubCachePath != null) { - pubEnv['PUB_CACHE'] = pubCachePath; - } - - var retryCount = 3; - ProcessResult result; - do { - retryCount--; - log.info('Running `pub upgrade`...'); - result = await Process.run('pub', ['upgrade', '--verbosity', 'all'], - workingDirectory: pkgPath, environment: pubEnv); - } while (result.exitCode != 0 && retryCount > 0); - return PubSummary.create( - result.exitCode, result.stdout, result.stderr, pkgPath); -} - -Future downloadPkg(String pkgName, - {Version version, String pubCachePath}) async { - var args = ['cache', 'add', '--verbose']; - - if (version != null) { - args.addAll(['--version', version.toString()]); - } - - args.add(pkgName); - - var pubEnv = new Map.from(_pubEnv); - if (pubCachePath != null) { - pubEnv['PUB_CACHE'] = pubCachePath; - } - - var result = - _handleErrors(await Process.run('pub', args, environment: pubEnv)); - - var match = _versionDownloadRexexp.allMatches(result.stdout.trim()).single; - - var pkgMatch = match[1]; - assert(pkgMatch == pkgName); - - var versionString = match[2]; - assert(versionString.endsWith('.')); - while (versionString.endsWith('.')) { - versionString = versionString.substring(0, versionString.length - 1); - } - - var downloadedVersion = new Version.parse(versionString); - - if (version != null) { - assert(downloadedVersion == version); - } - // now get all installed packages - result = _handleErrors( - await Process.run('pub', ['cache', 'list'], environment: pubEnv)); - - var json = JSON.decode(result.stdout) as Map; - - var location = json['packages'][pkgName][versionString]['location'] as String; + log.info("Downloading package..."); + PackageLocation pkgInfo = + await _pubEnv.getLocation(package, version: ver?.toString()); + String pkgDir = pkgInfo.location; + log.info("Package at $pkgDir"); + + log.info('Counting files...'); + var dartFiles = new SplayTreeSet.from( + await listFiles(pkgDir, endsWith: '.dart')); + + log.info("Checking formatting..."); + var unformattedFiles = new SplayTreeSet.from( + await _dartSdk.filesNeedingFormat(pkgDir)); + + log.info("Pub upgrade..."); + ProcessResult upgrade = await _pubEnv.runUpgrade(pkgDir); + var summary = PubSummary.create( + upgrade.exitCode, upgrade.stdout, upgrade.stderr, pkgDir); + log.info("Package version: ${summary.pkgVersion}"); + + Set analyzerItems; + try { + analyzerItems = await _pkgAnalyze(pkgDir); + } on ArgumentError catch (e) { + if (e.toString().contains("No dart files found at: .")) { + log.warning("No files to analyze..."); + analyzerItems = new Set(); + } else { + rethrow; + } + } - if (location == null) { - throw "Huh? This should be cached!"; + return new Summary(sdkVersion, package, new Version.parse(pkgInfo.version), + dartFiles, summary, analyzerItems, unformattedFiles); } - return new PkgInstallInfo(pkgName, downloadedVersion, location); -} - -class PkgInstallInfo { - final String name; - final Version version; - final String path; - - PkgInstallInfo(this.name, this.version, this.path); -} - -final _versionDownloadRexexp = - new RegExp(r"^MSG : (?:Downloading |Already cached )([\w-]+) (.+)$"); - -const _pubEnv = const {'PUB_ENVIRONMENT': 'kevmoo.pkg_clean'}; - -ProcessResult _handleErrors(ProcessResult result) { - if (result.exitCode != 0) { - if (result.exitCode == 69) { - // could be a pub error. Let's try to parse! - var lines = LineSplitter - .split(result.stderr) - .where((l) => l.startsWith("ERR ")) - .join('\n'); - if (lines.isNotEmpty) { - throw lines; - } + Future> _pkgAnalyze(String pkgPath) async { + log.info('Running `dartanalyzer`...'); + var proc = await _dartSdk.runAnalyzer(pkgPath); + + try { + return new SplayTreeSet.from(LineSplitter + .split(proc.stderr) + .map((s) => AnalyzerOutput.parse(s, projectDir: pkgPath)) + .where((e) => e != null)); + } on ArgumentError { + // TODO: we should figure out a way to succeed here, right? + // Or at least do partial results and not blow up + log.severe("Bad input?"); + log.severe(proc.stderr); + rethrow; } - - throw "Problem running proc: exit code - " + - [result.exitCode, result.stdout, result.stderr] - .map((e) => e.toString().trim()) - .join('<***>'); } - return result; } diff --git a/lib/src/pub_summary.dart b/lib/src/pub_summary.dart index a4a5befe4..9557011f6 100644 --- a/lib/src/pub_summary.dart +++ b/lib/src/pub_summary.dart @@ -4,38 +4,12 @@ import 'dart:io'; import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; -import 'package:yaml/yaml.dart'; + +import 'utils.dart'; final _prefix = new RegExp(r"(MSG| ) (:|\|) (?:\+| ) (.+)"); final _infoRegexp = new RegExp(r"(\w+) (\S+)(?: \((\S+) available\))?"); -_toSortedMap(Object item) { - if (item is Map) { - return new SplayTreeMap.fromIterable(item.keys, - value: (k) => _toSortedMap(item[k])); - } else if (item is List) { - return item.map(_toSortedMap).toList(); - } else { - return item; - } -} - -Object sortedJson(obj) { - var fullJson = JSON.decode(JSON.encode(obj)); - return _toSortedMap(fullJson); -} - -Map _yamlToJson(String pubspecContent) { - if (pubspecContent == null) { - return null; - } - var yamlMap = loadYaml(pubspecContent) as YamlMap; - - // A bit paranoid, but I want to make sure this is valid JSON before we got to - // the encode phase. - return sortedJson(JSON.decode(JSON.encode(yamlMap))); -} - class PubSummary { final int exitCode; final String stdoutValue; @@ -53,7 +27,7 @@ class PubSummary { this.availableVersions, String pubspecContent, this.lockFileContent) - : pubspec = _yamlToJson(pubspecContent); + : pubspec = yamlToJson(pubspecContent); static PubSummary create( int exitCode, String procStdout, String procStderr, String path) { diff --git a/lib/src/sdk_env.dart b/lib/src/sdk_env.dart new file mode 100644 index 000000000..671ed864b --- /dev/null +++ b/lib/src/sdk_env.dart @@ -0,0 +1,169 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'logging.dart'; +import 'utils.dart'; + +class DartSdk { + Map _environment = {}; + String _dartCmd; + String _dartAnalyzerCmd; + String _dartfmtCmd; + String _pubCmd; + String _version; + + DartSdk({String sdkDir, Map environment}) { + String path = ''; + if (sdkDir != null) { + path = sdkDir; + if (!sdkDir.endsWith(Platform.pathSeparator)) { + path += Platform.pathSeparator; + } + } + if (environment != null) { + _environment.addAll(environment); + } + _dartCmd = '${path}dart'; + _dartAnalyzerCmd = '${path}dartanalyzer'; + _dartfmtCmd = '${path}dartfmt'; + _pubCmd = '${path}pub'; + } + + Future get version async { + if (_version == null) { + var r = handleProcessErrors(await Process.run(_dartCmd, ['--version'], + environment: _environment)); + _version = r.stderr.toString().trim(); + } + return _version; + } + + Future runAnalyzer(String packageDir) { + return Process.run( + _dartAnalyzerCmd, + ['--strong', '--format', 'machine', '.'], + environment: _environment, + workingDirectory: packageDir, + ); + } + + Future> filesNeedingFormat(String packageDir) async { + var result = await Process.run( + _dartfmtCmd, + ['--dry-run', '--set-exit-if-changed', packageDir], + environment: _environment, + ); + if (result.exitCode == 0) { + return const []; + } + + var lines = LineSplitter.split(result.stdout).toList()..sort(); + assert(lines.isNotEmpty); + return lines; + } +} + +class PubEnvironment { + DartSdk _dartSdk; + String _pubCacheDir; + Map _environment = {}; + + PubEnvironment({DartSdk dartSdk, String pubCacheDir}) { + _dartSdk = dartSdk ?? new DartSdk(); + _environment.addAll(_defaultPubEnv); + _environment.addAll(_dartSdk._environment); + _pubCacheDir = pubCacheDir; + if (pubCacheDir != null) { + var resolvedDir = new Directory(pubCacheDir).resolveSymbolicLinksSync(); + if (resolvedDir != pubCacheDir) { + throw new ArgumentError([ + "Make sure you resolve symlinks:", + pubCacheDir, + resolvedDir + ].join('\n')); + } + _environment['PUB_CACHE'] = pubCacheDir; + } + } + + DartSdk get sdk => _dartSdk; + String get pubCacheDir => _pubCacheDir; + + Future runUpgrade(String packageDir, + {int retryCount: 3}) async { + ProcessResult result; + do { + retryCount--; + log.info('Running `pub upgrade`...'); + result = await Process.run( + _dartSdk._pubCmd, + ['upgrade', '--verbosity', 'all'], + workingDirectory: packageDir, + environment: _environment, + ); + } while (result.exitCode != 0 && retryCount > 0); + return result; + } + + Future getLocation(String package, {String version}) async { + var args = ['cache', 'add', '--verbose']; + if (version != null) { + args.addAll(['--version', version]); + } + args.add(package); + + var result = handleProcessErrors(await Process.run( + _dartSdk._pubCmd, + args, + environment: _environment, + )); + + var match = _versionDownloadRexexp.allMatches(result.stdout.trim()).single; + var pkgMatch = match[1]; + assert(pkgMatch == package); + + var versionString = match[2]; + assert(versionString.endsWith('.')); + while (versionString.endsWith('.')) { + versionString = versionString.substring(0, versionString.length - 1); + } + + if (version != null) { + assert(versionString == version); + } + + // now get all installed packages + result = handleProcessErrors(await Process.run( + _dartSdk._pubCmd, + ['cache', 'list'], + environment: _environment, + )); + + var json = JSON.decode(result.stdout) as Map; + + var location = + json['packages'][package][versionString]['location'] as String; + + if (location == null) { + throw "Huh? This should be cached!"; + } + + return new PackageLocation(package, versionString, location); + } +} + +class PackageLocation { + final String package; + final String version; + final String location; + + PackageLocation(this.package, this.version, this.location); +} + +final _versionDownloadRexexp = + new RegExp(r"^MSG : (?:Downloading |Already cached )([\w-]+) (.+)$"); + +const _defaultPubEnv = const { + 'PUB_ENVIRONMENT': 'kevmoo.pkg_clean', +}; diff --git a/lib/src/utils.dart b/lib/src/utils.dart new file mode 100644 index 000000000..6f12b5f97 --- /dev/null +++ b/lib/src/utils.dart @@ -0,0 +1,70 @@ +import 'dart:async'; +import 'dart:collection'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:path/path.dart' as p; +import 'package:yaml/yaml.dart'; + +ProcessResult handleProcessErrors(ProcessResult result) { + if (result.exitCode != 0) { + if (result.exitCode == 69) { + // could be a pub error. Let's try to parse! + var lines = LineSplitter + .split(result.stderr) + .where((l) => l.startsWith("ERR ")) + .join('\n'); + if (lines.isNotEmpty) { + throw lines; + } + } + + throw "Problem running proc: exit code - " + + [result.exitCode, result.stdout, result.stderr] + .map((e) => e.toString().trim()) + .join('<***>'); + } + return result; +} + +Future> listFiles(String directory, {String endsWith}) { + Directory dir = new Directory(directory); + return dir + .list(recursive: true) + .where((fse) => fse is File) + .map((fse) => fse.path) + .where((path) => endsWith == null || path.endsWith(endsWith)) + .map((path) => p.relative(path, from: directory)) + .toList(); +} + +String prettyJson(obj) => + const JsonEncoder.withIndent(' ').convert(obj).trim(); + + +Object sortedJson(obj) { + var fullJson = JSON.decode(JSON.encode(obj)); + return _toSortedMap(fullJson); +} + +_toSortedMap(Object item) { + if (item is Map) { + return new SplayTreeMap.fromIterable(item.keys, + value: (k) => _toSortedMap(item[k])); + } else if (item is List) { + return item.map(_toSortedMap).toList(); + } else { + return item; + } +} + +Map yamlToJson(String pubspecContent) { + if (pubspecContent == null) { + return null; + } + var yamlMap = loadYaml(pubspecContent) as YamlMap; + + // A bit paranoid, but I want to make sure this is valid JSON before we got to + // the encode phase. + return sortedJson(JSON.decode(JSON.encode(yamlMap))); +} diff --git a/test/end2end/pub_server-0.1.1+3.json b/test/end2end/pub_server-0.1.1+3.json new file mode 100644 index 000000000..63559afae --- /dev/null +++ b/test/end2end/pub_server-0.1.1+3.json @@ -0,0 +1,167 @@ +{ + "sdkVersion": "[MASKED]", + "packageName": "pub_server", + "packageVersion": "0.1.1+3", + "dartFiles": [ + "example/server.dart", + "example/src/examples/cow_repository.dart", + "example/src/examples/file_repository.dart", + "example/src/examples/http_proxy_repository.dart", + "lib/repository.dart", + "lib/shelf_pubserver.dart", + "test/shelf_pubserver_test.dart" + ], + "pubSummary": { + "packages": { + "analyzer": "0.30.0+2", + "archive": "1.0.28", + "args": "0.13.7", + "async": "1.13.3", + "barback": "0.15.2+11", + "boolean_selector": "1.0.2", + "charcode": "1.1.1", + "cli_util": "0.1.0", + "collection": "1.14.1", + "convert": "2.0.1", + "crypto": "2.0.1", + "csslib": "0.13.7+1", + "front_end": "0.1.0-alpha.4", + "glob": "1.1.3", + "html": "0.13.1", + "http": "0.11.3+13", + "http_multi_server": "2.0.3", + "http_parser": "3.1.1", + "isolate": "1.0.0", + "kernel": "0.3.0-alpha.1", + "logging": "0.11.3+1", + "matcher": "0.12.1", + "meta": "1.0.5", + "mime": "0.9.3", + "package_config": "1.0.1", + "package_resolver": "1.0.2", + "path": "1.4.1", + "plugin": "0.2.0", + "pool": "1.3.1", + "pub_semver": "1.3.2", + "shelf": "0.6.7+2", + "shelf_packages_handler": "1.0.0", + "shelf_static": "0.2.4", + "shelf_web_socket": "0.2.1", + "source_map_stack_trace": "1.1.4", + "source_maps": "0.10.4", + "source_span": "1.4.0", + "stack_trace": "1.7.3", + "stream_channel": "1.6.1", + "string_scanner": "1.0.2", + "term_glyph": "1.0.0", + "test": "0.12.20+13", + "typed_data": "1.1.3", + "utf": "0.9.0+3", + "watcher": "0.9.7+3", + "web_socket_channel": "1.0.4", + "yaml": "2.1.12" + }, + "availablePackages": {}, + "pubspecContent": { + "author": "Dart Team ", + "dependencies": { + "logging": ">=0.9.3 <1.0.0", + "mime": ">=0.9.3 <0.10.0", + "pub_semver": ">=1.1.0 <1.4.0", + "shelf": ">=0.5.6 <0.7.0", + "yaml": ">=2.1.2 <3.0.0" + }, + "description": "A Dart package containing re-usable components for making a pub package server.", + "dev_dependencies": { + "archive": ">=1.0.0 <2.0.0", + "args": ">=0.12.2 <0.14.0", + "http": ">0.11.0 <0.12.0", + "test": ">=0.12.0 <0.13.0" + }, + "environment": { + "sdk": ">=1.5.0 <2.0.0" + }, + "homepage": "https://github.com/dart-lang/pub_server", + "name": "pub_server", + "version": "0.1.1+3" + } + }, + "analyzerItems": [ + { + "type": "ERROR|COMPILE_TIME_ERROR|STRONG_MODE_INVALID_METHOD_OVERRIDE", + "file": "example/src/examples/cow_repository.dart", + "line": 89, + "col": 3, + "error": "Invalid override. The type of 'CopyAndWriteRepository.upload' ('(Stream>) → Future') isn't a subtype of 'PackageRepository.upload' ('(Stream>) → Future')." + }, + { + "type": "ERROR|COMPILE_TIME_ERROR|STRONG_MODE_INVALID_CAST_FUNCTION_EXPR", + "file": "example/src/examples/file_repository.dart", + "line": 31, + "col": 16, + "error": "The function expression type '(Directory) → PackageVersion' isn't of type '(FileSystemEntity) → PackageVersion'. This means its parameter or return type does not match what is expected. Consider changing parameter type(s) or the returned type(s)." + }, + { + "type": "ERROR|COMPILE_TIME_ERROR|STRONG_MODE_INVALID_METHOD_OVERRIDE", + "file": "example/src/examples/file_repository.dart", + "line": 59, + "col": 3, + "error": "Invalid override. The type of 'FileRepository.upload' ('(Stream>) → Future') isn't a subtype of 'PackageRepository.upload' ('(Stream>) → Future')." + }, + { + "type": "INFO|HINT|DEPRECATED_MEMBER_USE", + "file": "test/shelf_pubserver_test.dart", + "line": 215, + "col": 54, + "error": "'expectAsync' is deprecated and shouldn't be used." + }, + { + "type": "INFO|HINT|DEPRECATED_MEMBER_USE", + "file": "test/shelf_pubserver_test.dart", + "line": 236, + "col": 54, + "error": "'expectAsync' is deprecated and shouldn't be used." + }, + { + "type": "INFO|HINT|DEPRECATED_MEMBER_USE", + "file": "test/shelf_pubserver_test.dart", + "line": 239, + "col": 21, + "error": "'expectAsync' is deprecated and shouldn't be used." + }, + { + "type": "INFO|HINT|DEPRECATED_MEMBER_USE", + "file": "test/shelf_pubserver_test.dart", + "line": 362, + "col": 32, + "error": "'expectAsync' is deprecated and shouldn't be used." + }, + { + "type": "INFO|HINT|DEPRECATED_MEMBER_USE", + "file": "test/shelf_pubserver_test.dart", + "line": 415, + "col": 32, + "error": "'expectAsync' is deprecated and shouldn't be used." + }, + { + "type": "INFO|HINT|DEPRECATED_MEMBER_USE", + "file": "test/shelf_pubserver_test.dart", + "line": 506, + "col": 31, + "error": "'expectAsync' is deprecated and shouldn't be used." + }, + { + "type": "INFO|HINT|DEPRECATED_MEMBER_USE", + "file": "test/shelf_pubserver_test.dart", + "line": 559, + "col": 34, + "error": "'expectAsync' is deprecated and shouldn't be used." + } + ], + "unformattedFiles": [ + "example/src/examples/cow_repository.dart", + "example/src/examples/http_proxy_repository.dart", + "lib/shelf_pubserver.dart", + "test/shelf_pubserver_test.dart" + ] +} \ No newline at end of file diff --git a/test/end2end_test.dart b/test/end2end_test.dart new file mode 100644 index 000000000..14903fe55 --- /dev/null +++ b/test/end2end_test.dart @@ -0,0 +1,39 @@ +import 'dart:io'; + +import 'package:pana/pana.dart'; +import 'package:test/test.dart'; + +void main() { + void expectGoldenSummary(Summary summary) { + Map actualMap = summary.toJson(); + actualMap['sdkVersion'] = '[MASKED]'; + String actual = prettyJson(actualMap); + + String goldenPath = + 'test/end2end/${summary.packageName}-${summary.packageVersion}.json'; + String golden = new File(goldenPath).readAsStringSync(); + + expect(actual.split('\n'), golden.split('\n')); + } + + group('PackageAnalyzer', () { + Directory tempDir; + String pubCacheDir; + + setUpAll(() async { + tempDir = await Directory.systemTemp.createTemp('pana-test'); + pubCacheDir = await tempDir.resolveSymbolicLinks(); + }); + + tearDownAll(() async { + await tempDir.delete(recursive: true); + }); + + test('pub_server 0.1.1+3', () async { + var analyzer = new PackageAnalyzer(pubCacheDir: pubCacheDir); + var summary = + await analyzer.inspectPackage('pub_server', version: '0.1.1+3'); + expectGoldenSummary(summary); + }); + }); +} diff --git a/test/pana_test.dart b/test/pub_summary_test.dart similarity index 92% rename from test/pana_test.dart rename to test/pub_summary_test.dart index 54134f00d..0f52f9e67 100644 --- a/test/pana_test.dart +++ b/test/pub_summary_test.dart @@ -1,24 +1,11 @@ // Copyright (c) 2017, Kevin Moore. All rights reserved. Use of this source code // is governed by a BSD-style license that can be found in the LICENSE file. -import 'dart:convert'; - import 'package:pana/src/pub_summary.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; void main() { - test("sorted json", () { - expect( - JSON.encode(sortedJson({ - 'b': [ - {'e': 3, 'd': 4} - ], - 'a': 2 - })), - '{"a":2,"b":[{"d":4,"e":3}]}'); - }); - test('pub parse', () { var summary = PubSummary.create(0, _pubUpgradeOutput, '', null); diff --git a/test/utils_test.dart b/test/utils_test.dart new file mode 100644 index 000000000..46c8c9f77 --- /dev/null +++ b/test/utils_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2017, Kevin Moore. All rights reserved. Use of this source code +// is governed by a BSD-style license that can be found in the LICENSE file. + +import 'dart:convert'; + +import 'package:pana/src/utils.dart'; +import 'package:test/test.dart'; + +void main() { + test("sorted json", () { + expect( + JSON.encode(sortedJson({ + 'b': [ + {'e': 3, 'd': 4} + ], + 'a': 2 + })), + '{"a":2,"b":[{"d":4,"e":3}]}'); + }); + +}