This repository was archived by the owner on Dec 6, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit fc062a7
Showing
8 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
packages | ||
pubspec.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
spawn = require('child_process').spawn | ||
|
||
DART_VM = process.env.DART_VM or '../dart-sdk/bin/dart' | ||
|
||
module.exports = (grunt) -> | ||
grunt.initConfig | ||
watch: | ||
tests: | ||
files: ['test/**/*.dart', 'lib/**/*.dart'] | ||
tasks: ['dart'] | ||
dart: | ||
tests: | ||
entry: 'test/main.dart' | ||
|
||
grunt.registerMultiTask 'dart', 'run dart program', -> | ||
spawn(DART_VM, [@data.entry], {stdio: 'inherit'}).on 'close', @async() | ||
|
||
grunt.loadNpmTasks 'grunt-contrib-watch' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import 'mirrors.dart'; | ||
import 'dart:async'; | ||
|
||
class Injector { | ||
// should be <Type,Type> | ||
Map<String, String> providers = new Map<String, String>(); | ||
// should be <Type, dynamic> | ||
Map<String, dynamic> instances = new Map<String, dynamic>(); | ||
|
||
Injector([Map types]) { | ||
if (types != null) { | ||
// create <String,String> map, because Dart is stupid and makes us deal with strings rather than types | ||
types.forEach((key, value) { | ||
providers[key.toString()] = value.toString(); | ||
}); | ||
} | ||
} | ||
|
||
ClassMirror _getClassMirrorByTypeName (String typeName) { | ||
// overriden provider | ||
if (providers.containsKey(typeName)) { | ||
typeName = providers[typeName]; | ||
} | ||
|
||
for (var lib in currentMirrorSystem().libraries.values) { | ||
if (lib.classes.containsKey(typeName)) { | ||
return lib.classes[typeName]; | ||
} | ||
} | ||
} | ||
|
||
ClassMirror _getClassMirrorFromType(Type type) { | ||
// terrible hack because we can't get a qualified name from a Type | ||
// dartbug.com/8041 | ||
// dartbug.com/9395 | ||
return _getClassMirrorByTypeName(type.toString()); | ||
} | ||
|
||
|
||
dynamic _getInstanceByTypeName(String typeName) { | ||
if (instances.containsKey(typeName)) { | ||
return instances[typeName]; | ||
} | ||
|
||
ClassMirror cm = _getClassMirrorByTypeName(typeName); | ||
MethodMirror ctor = cm.constructors.values.first; | ||
|
||
resolveArgument(p) { | ||
return _getInstanceByTypeName(p.type.simpleName); | ||
} | ||
|
||
var positionalArgs = ctor.parameters.map(resolveArgument).toList(); | ||
var namedArgs = null; | ||
var instance = deprecatedFutureValue(cm.newInstance(ctor.constructorName, positionalArgs, namedArgs)); | ||
|
||
instances[typeName] = instance; | ||
|
||
return instance; | ||
} | ||
|
||
|
||
// PUBLIC API | ||
dynamic get(Type type) { | ||
return _getInstanceByTypeName(type.toString()).reflectee; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// just to get rid of the warning | ||
library mirrors; | ||
|
||
export 'dart:mirrors'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"name": "dart-di", | ||
"version": "0.0.0", | ||
"description": "ERROR: No README.md file found!", | ||
"main": "index.js", | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"grunt": "~0.4", | ||
"grunt-contrib-watch": "~0.3" | ||
}, | ||
"scripts": { | ||
"test": "grunt dart:test" | ||
}, | ||
"repository": "", | ||
"author": "Vojta Jina <[email protected]>", | ||
"license": "MIT" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
name: di | ||
description: A prototype of Dependency Injection framework. | ||
version: 0.0.1 | ||
author: "Vojta Jina <[email protected]>" | ||
homepage: https://github.com/dart-lang/dado | ||
|
||
dev_dependencies: | ||
unittest: any |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
library unittest; | ||
|
||
import 'package:unittest/unittest.dart'; | ||
import '../lib/mirrors.dart'; | ||
|
||
export 'package:unittest/unittest.dart'; | ||
|
||
// fix the testing framework ;-) | ||
void it(String spec, TestFunction body) => test(spec, body); | ||
void xit(String spec, TestFunction body) {} | ||
void iit(String spec, TestFunction body) => solo_test(spec, body); | ||
|
||
Matcher toEqual(expected) => equals(expected); | ||
Matcher toBe(expected) => same(expected); | ||
Matcher instanceOf(Type t) => new IsInstanceOfTypeMatcher(t); | ||
|
||
|
||
// Welcome to Dart ;-) | ||
class IsInstanceOfTypeMatcher extends BaseMatcher { | ||
Type t; | ||
|
||
IsInstanceOfTypeMatcher(Type t) { | ||
this.t = t; | ||
} | ||
|
||
bool matches(obj, MatchState matchState) { | ||
// we should at least compare qualifiedName, but there's no way to get it from Type | ||
return reflect(obj).type.simpleName == t.toString(); | ||
} | ||
|
||
Description describe(Description description) => | ||
description.add('an instance of ${t.toString()}'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import 'fixed-unittest.dart'; | ||
import 'package:di/di.dart'; | ||
|
||
// just some classes for testing | ||
class Abc { | ||
String id = 'abc-id'; | ||
|
||
void greet() { | ||
print('HELLO'); | ||
} | ||
} | ||
|
||
class MockAbc implements Abc { | ||
String id = 'mock-id'; | ||
|
||
void greet() { | ||
print('MOCK HELLO'); | ||
} | ||
} | ||
|
||
class Complex { | ||
Abc value; | ||
|
||
Complex(Abc val) { | ||
value = val; | ||
} | ||
|
||
dynamic getValue() { | ||
return value; | ||
} | ||
} | ||
|
||
|
||
// pretend, you don't see this main method | ||
void main() { | ||
|
||
it('should instantiate a type', () { | ||
var injector = new Injector(); | ||
var instance = injector.get(Abc); | ||
|
||
expect(instance, instanceOf(Abc)); | ||
expect(instance.id, toEqual('abc-id')); | ||
}); | ||
|
||
|
||
it('should resolve basic dependencies', () { | ||
var injector = new Injector(); | ||
var instance = injector.get(Complex); | ||
|
||
expect(instance, instanceOf(Complex)); | ||
expect(instance.getValue().id, toEqual('abc-id')); | ||
}); | ||
|
||
|
||
it('should allow modules and overriding providers', () { | ||
// module is just a Map<Type, Type> | ||
var module = new Map<Type, Type>(); | ||
module[Abc] = MockAbc; | ||
|
||
// injector is immutable | ||
// you can't load more modules once it's instantiated | ||
// (you can create a child injector) | ||
var injector = new Injector(module); | ||
var instance = injector.get(Abc); | ||
|
||
expect(instance.id, toEqual('mock-id')); | ||
}); | ||
|
||
|
||
it('should only create a single instance', () { | ||
var injector = new Injector(); | ||
var first = injector.get(Abc); | ||
var second = injector.get(Abc); | ||
|
||
expect(first, toBe(second)); | ||
}); | ||
|
||
} |