Verified tests on Dart 1 + 2

This commit is contained in:
Tobe O 2018-07-12 12:40:54 -04:00
parent 7b1dd6d86c
commit 4e3e8de157
11 changed files with 30 additions and 196 deletions

5
.gitignore vendored
View file

@ -1,6 +1,7 @@
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
.idea
*.iml
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
@ -73,4 +74,6 @@ doc/api/
# Don't commit pubspec lock file
# (Library packages only! Remove pattern if developing an application package)
pubspec.lock
pubspec.lock
.dart_tool

View file

@ -1 +1,4 @@
language: dart
language: dart
dart:
- dev
- stable

View file

@ -1,3 +1,8 @@
# 2.0.0
* Removed the `Configuration` class.
* Removed the `ConfigurationTransformer` class.
* Use `Map` casting to prevent runtime cast errors.
# 1.0.5
* Now using `package:merge_map` to merge configurations. Resolves
[#5](https://github.com/angel-dart/configuration/issues/5).

View file

@ -98,29 +98,4 @@ foo:
bar: baz
quux: goodbye
yellow: submarine
```
**In the Browser**
You can easily load configuration values within your client-side app,
and they will be automatically replaced by a Barback transformer.
In your `pubspec.yaml`:
```yaml
transformers:
- angel_configuration
```
In your app:
```dart
import 'package:angel_configuration/browser.dart';
main() async {
print(config("some_key.other.nested_key"));
}
```
You can also provide a `dir` or `env` argument, corresponding to
the ones on the server-side.
```

View file

@ -1,2 +1,3 @@
analyzer:
strong-mode: true
strong-mode:
implicit-casts: true

9
example/main.dart Normal file
View file

@ -0,0 +1,9 @@
import 'package:angel_configuration/angel_configuration.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:file/local.dart';
main() async {
var app = new Angel();
var fs = const LocalFileSystem();
await app.configure(configuration(fs));
}

View file

@ -6,35 +6,6 @@ import 'package:file/file.dart';
import 'package:merge_map/merge_map.dart';
import 'package:yaml/yaml.dart';
final RegExp _equ = new RegExp(r'=$');
final RegExp _sym = new RegExp(r'Symbol\("([^"]+)"\)');
/// A proxy object that encapsulates a server's configuration.
@proxy
class Configuration {
/// The [Angel] instance that loaded this configuration.
final Angel app;
Configuration(this.app);
operator [](key) => app.configuration[key];
operator []=(key, value) => app.configuration[key] = value;
noSuchMethod(Invocation invocation) {
if (invocation.memberName != null) {
String name = _sym.firstMatch(invocation.memberName.toString()).group(1);
if (invocation.isMethod) {
return Function.apply(app.configuration[name],
invocation.positionalArguments, invocation.namedArguments);
} else if (invocation.isGetter) {
return app.configuration[name];
}
}
super.noSuchMethod(invocation);
}
}
_loadYamlFile(Angel app, File yamlFile, Map<String, String> env) async {
if (await yamlFile.exists()) {
var config = loadYaml(await yamlFile.readAsString());
@ -89,8 +60,7 @@ _applyEnv(var v, Map<String, String> env, Angel app) {
/// load from a [overrideEnvironmentName].
///
/// You can also specify a custom [envPath] to load system configuration from.
AngelConfigurer configuration(
FileSystem fileSystem,
AngelConfigurer configuration(FileSystem fileSystem,
{String directoryPath: "./config",
String overrideEnvironmentName,
String envPath}) {
@ -121,6 +91,5 @@ AngelConfigurer configuration(
var configFile = sourceDirectory.childFile(configFilePath);
await _loadYamlFile(app, configFile, env);
app.container.singleton(new Configuration(app));
};
}

View file

@ -1,101 +0,0 @@
import 'dart:async';
import 'dart:convert';
import 'package:barback/barback.dart';
import 'package:analyzer/analyzer.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:file/local.dart';
import 'angel_configuration.dart';
class ConfigurationTransformer extends Transformer {
final BarbackSettings _settings;
@override
String get allowedExtensions => ".dart";
ConfigurationTransformer.asPlugin(this._settings) {}
Future apply(Transform transform) async {
try {
var app = new Angel();
await app.configure(configuration(
const LocalFileSystem(),
directoryPath: _settings.configuration["dir"] ?? "./config",
overrideEnvironmentName: _settings.configuration["env"],
));
var text = await transform.primaryInput.readAsString();
var compilationUnit = parseCompilationUnit(text);
var visitor = new ConfigAstVisitor(app.properties);
visitor.visitCompilationUnit(compilationUnit);
await for (Map replaced in visitor.onReplaced) {
text = text.replaceAll(replaced["needle"], replaced["with"]);
}
transform
.addOutput(new Asset.fromString(transform.primaryInput.id, text));
} catch (e) {
// Fail silently...
}
}
}
class ConfigAstVisitor extends GeneralizingAstVisitor {
Map _config;
var _onReplaced = new StreamController<Map>();
String _prefix = "";
Stream<Map> get onReplaced => _onReplaced.stream;
ConfigAstVisitor(this._config);
bool isConfigMethod(Expression function) =>
function is SimpleIdentifier && function.name == "${_prefix}config";
resolveItem(String key) {
var split = key.split(".");
var parent = _config;
for (int i = 0; i < split.length; i++) {
if (parent != null && parent is Map) parent = parent[split[i]];
}
return parent;
}
@override
visitCompilationUnit(CompilationUnit ctx) {
var result = super.visitCompilationUnit(ctx);
_onReplaced.close();
return result;
}
@override
visitImportDirective(ImportDirective ctx) {
String uri = ctx.uri.stringValue;
if (uri == "package:angel_configuration/browser.dart") {
_onReplaced.add({"needle": ctx.toString(), "with": ""});
if (ctx.asKeyword != null) {
_prefix = ctx.prefix.name;
}
}
return super.visitImportDirective(ctx);
}
@override
visitExpression(Expression ctx) {
if (ctx is MethodInvocation) {
if (isConfigMethod(ctx.function)) {
StringLiteral key = ctx.argumentList.arguments[0];
var resolved = resolveItem(key.stringValue);
_onReplaced
.add({"needle": ctx.toString(), "with": JSON.encode(resolved)});
}
}
return super.visitExpression(ctx);
}
}

View file

@ -1,15 +1,14 @@
name: angel_configuration
description: Automatic YAML configuration loader for Angel.
version: 1.1.0
version: 2.0.0-rc.0
author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/angel_configuration
environment:
sdk: ">=1.19.0"
sdk: ">=1.8.0 <3.0.0"
dependencies:
analyzer: ">=0.28.1 <1.0.0"
angel_framework: ^1.1.0-alpha
barback: ^0.15.2
dotenv: ^0.1.0
dotenv:
git: https://github.com/thosakwe/dotenv.git
file: ^2.0.0
merge_map: ^1.0.0
yaml: ^2.0.0

View file

@ -2,7 +2,6 @@ import 'package:angel_framework/angel_framework.dart';
import 'package:angel_configuration/angel_configuration.dart';
import 'package:file/local.dart';
import 'package:test/test.dart';
import 'transformer.dart' as transformer;
main() async {
// Note: Set ANGEL_ENV to 'development'
@ -45,6 +44,4 @@ main() async {
directoryPath: './test/config', overrideEnvironmentName: 'override'));
expect(app.configuration['merge'], {'map': true, 'hello': 'goodbye'});
});
group("transformer", transformer.main);
}

View file

@ -1,26 +0,0 @@
import 'package:analyzer/analyzer.dart';
import 'package:angel_configuration/transformer.dart';
import 'package:test/test.dart';
main() {
test("simple replacement", () async {
var visitor = new ConfigAstVisitor({"foo": "bar"});
var source = '''
import 'package:angel_configuration/browser.dart';
main() async {
var foo = config('foo');
}
''';
var compilationUnit = parseCompilationUnit(source);
visitor.visitCompilationUnit(compilationUnit);
var replaced = await visitor.onReplaced.take(2).last;
expect(replaced["needle"], equals("config('foo')"));
expect(replaced["with"], equals('"bar"'));
print(source.replaceAll(replaced["needle"], replaced["with"]));
});
}