diff --git a/lib/src/html/html_generator_instance.dart b/lib/src/html/html_generator_instance.dart
index 3fbe70779e..79052eccbc 100644
--- a/lib/src/html/html_generator_instance.dart
+++ b/lib/src/html/html_generator_instance.dart
@@ -15,8 +15,8 @@ import 'package:dartdoc/src/html/templates.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:dartdoc/src/model.dart';
import 'package:dartdoc/src/model_utils.dart';
-import 'package:dartdoc/src/third_party/pkg/mustache4dart/lib/mustache4dart.dart';
import 'package:dartdoc/src/warnings.dart';
+import 'package:mustache/mustache.dart';
import 'package:path/path.dart' as pathLib;
typedef void FileWriter(String path, Object content, {bool allowOverwrite});
@@ -377,9 +377,8 @@ class HtmlGeneratorInstance {
}
}
- void _build(String filename, TemplateRenderer template, TemplateData data) {
- String content = template(data,
- assumeNullNonExistingProperty: false, errorOnMissingProperty: true);
+ void _build(String filename, Template template, TemplateData data) {
+ String content = template.renderString(data);
_writer(filename, content);
if (data.self is Indexable) _indexedElements.add(data.self as Indexable);
diff --git a/lib/src/html/templates.dart b/lib/src/html/templates.dart
index 55f1a2f3eb..178c40e161 100644
--- a/lib/src/html/templates.dart
+++ b/lib/src/html/templates.dart
@@ -8,7 +8,7 @@ import 'dart:async' show Future;
import 'dart:io' show File;
import 'package:dartdoc/src/html/resource_loader.dart' as loader;
-import 'package:dartdoc/src/third_party/pkg/mustache4dart/lib/mustache4dart.dart';
+import 'package:mustache/mustache.dart';
const _partials = const [
'callable',
@@ -83,21 +83,21 @@ Future _getTemplateFile(String templateFileName) =>
loader.loadAsString('package:dartdoc/templates/$templateFileName');
class Templates {
- final TemplateRenderer categoryTemplate;
- final TemplateRenderer classTemplate;
- final TemplateRenderer enumTemplate;
- final TemplateRenderer constantTemplate;
- final TemplateRenderer constructorTemplate;
- final TemplateRenderer errorTemplate;
- final TemplateRenderer functionTemplate;
- final TemplateRenderer indexTemplate;
- final TemplateRenderer libraryTemplate;
- final TemplateRenderer methodTemplate;
- final TemplateRenderer mixinTemplate;
- final TemplateRenderer propertyTemplate;
- final TemplateRenderer topLevelConstantTemplate;
- final TemplateRenderer topLevelPropertyTemplate;
- final TemplateRenderer typeDefTemplate;
+ final Template categoryTemplate;
+ final Template classTemplate;
+ final Template enumTemplate;
+ final Template constantTemplate;
+ final Template constructorTemplate;
+ final Template errorTemplate;
+ final Template functionTemplate;
+ final Template indexTemplate;
+ final Template libraryTemplate;
+ final Template methodTemplate;
+ final Template mixinTemplate;
+ final Template propertyTemplate;
+ final Template topLevelConstantTemplate;
+ final Template topLevelPropertyTemplate;
+ final Template typeDefTemplate;
static Future create(
{List headerPaths,
@@ -106,17 +106,17 @@ class Templates {
var partials =
await _loadPartials(headerPaths, footerPaths, footerTextPaths);
- String _partial(String name) {
+ Template _partial(String name) {
String partial = partials[name];
if (partial == null || partial.isEmpty) {
throw new StateError('Did not find partial "$name"');
}
- return partial;
+ return Template(partial);
}
- Future _loadTemplate(String templatePath) async {
+ Future _loadTemplate(String templatePath) async {
String templateContents = await _getTemplateFile(templatePath);
- return compile(templateContents, partial: _partial);
+ return Template(templateContents, partialResolver: _partial);
}
var indexTemplate = await _loadTemplate('index.html');
diff --git a/lib/src/third_party/pkg/000-mustache4dart-pubspec.patch b/lib/src/third_party/pkg/000-mustache4dart-pubspec.patch
deleted file mode 100644
index 330303022f..0000000000
--- a/lib/src/third_party/pkg/000-mustache4dart-pubspec.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- mustache4dart/pubspec.yaml.old 2018-08-06 10:02:45.152305202 -0700
-+++ mustache4dart/pubspec.yaml 2018-08-06 10:02:53.036245297 -0700
-@@ -4,7 +4,7 @@
- description: A mustache implementation for the Dart language
- homepage: https://github.com/valotas/mustache4dart
- environment:
-- sdk: '>=0.8.10+6 <2.0.0'
-+ sdk: '>=0.8.10+6 <3.0.0'
- dev_dependencies:
- test: '>=0.12.0 <0.12.23'
- isolate: '>=1.0.0 <1.1.0'
diff --git a/lib/src/third_party/pkg/001-mustache4dart-import-rewrite.patch b/lib/src/third_party/pkg/001-mustache4dart-import-rewrite.patch
deleted file mode 100644
index 40fa0707ee..0000000000
--- a/lib/src/third_party/pkg/001-mustache4dart-import-rewrite.patch
+++ /dev/null
@@ -1,1023 +0,0 @@
-diff -urN mustache4dart.orig/example/simpleusage.dart mustache4dart/example/simpleusage.dart
---- mustache4dart.orig/example/simpleusage.dart 2018-08-07 12:35:31.521479520 -0700
-+++ mustache4dart/example/simpleusage.dart 2018-08-07 12:38:54.608005680 -0700
-@@ -1,6 +1,6 @@
- library mustache_usage;
-
--import 'package:mustache4dart/mustache4dart.dart';
-+import '../lib/mustache4dart.dart';
-
- void main() {
- //Basic use of the library as you can find it at http://mustache.github.io/mustache.5.html
-diff -urN mustache4dart.orig/lib/mustache_context.dart mustache4dart/lib/mustache_context.dart
---- mustache4dart.orig/lib/mustache_context.dart 2018-08-07 12:31:09.343380762 -0700
-+++ mustache4dart/lib/mustache_context.dart 2018-08-07 12:38:19.776258618 -0700
-@@ -2,7 +2,7 @@
-
- import 'dart:collection';
-
--import 'package:mustache4dart/src/mirrors.dart';
-+import '../lib/src/mirrors.dart';
-
- const String DOT = '\.';
-
-diff -urN mustache4dart.orig/test/lorem-ipsum.txt mustache4dart/test/lorem-ipsum.txt
---- mustache4dart.orig/test/lorem-ipsum.txt 2018-08-07 12:11:27.844018370 -0700
-+++ mustache4dart/test/lorem-ipsum.txt 1969-12-31 16:00:00.000000000 -0800
-@@ -1,11 +0,0 @@
--Lorem ipsum dolor sit amet, est vel euismod et dictum fermentum integer, tortor ipsam est. Sollicitudin imperdiet fringilla placerat eros luctus facilisi, pede nunc, congue nullam dolor. Nibh neque urna neque, praesent volutpat tincidunt maecenas, scelerisque est, vitae in scelerisque placerat lacus, eu vitae lectus malesuada. Vehicula suspendisse tincidunt, aenean ac eros varius lectus quis. Orci lacus luctus nullam arcu id risus, odio feugiat turpis nullam suspendisse metus suspendisse, ligula vehicula nec fermentum ligula, convallis ultrices cras nibh eu. Leo pede iaculis mus risus, proin aliquam phasellus dui pretium arcu, pede fringilla risus, tempus odio sem lobortis lectus sem enim, laoreet donec posuere. Tempus elit vel arcu. A iaculis. A amet felis, sed sit metus. Quis etiam vitae at ipsum, et nam a. In auctor molestie suscipit enim ultrices tincidunt, nullam mi, hendrerit integer quisque elementum nonummy, enim pede magna, dui at dignissim vestibulum molestie et. Vel mattis aliquet, nulla nostra laoreet et ultrices, luctus luctus tortor libero augue orci id.
--
--Ante proin aenean sit elit, vel at donec lobortis eget, erat curabitur sed tempus enim, et et mollis sed in ultricies ultricies, rutrum alias porttitor erat. Convallis in voluptatum a a. Nunc odio cras ut consequat neque, in dolor nec, suspendisse et a cras consectetuer ut, in sagittis in dis blandit sit nisl, eros consequat. Arcu enim pede mattis adipiscing wisi facilisi, adipiscing morbi integer ante auctor. Porttitor lectus scelerisque pellentesque torquent, viverra donec enim. Quam vehicula sed eu, viverra dolor et sed mollis in, vulputate integer tristique elit tellus laoreet aut, sed dis adipiscing fames integer turpis, curabitur tellus velit nonummy et nam.
--
--Elit dolor maecenas vestibulum sodales ut, molestie luctus proin sit dolor mauris. In a lectus arcu, ut dui, nec molestie wisi tempus urna. Mollis imperdiet in lectus justo, pede justo nec vulputate commodo eget tincidunt, sapien tellus volutpat lacinia lectus. Ut dis tellus neque ac at sapien, ultrices vivamus bibendum mattis. Dui quisque, sed vivamus accumsan pellentesque, est donec sem. Tincidunt dignissim, vivamus aliquam lacinia neque, est integer. Turpis habitant id tempus vestibulum. Purus massa feugiat at ut massa varius, vivamus diam hendrerit tincidunt.
--Vitae mi fermentum a nec vehicula imperdiet, ipsum potenti suspendisse ipsum porta turpis, nam maecenas. Velit nulla a consectetuer arcu accumsan vitae, sodales cras in vitae leo eu, aliquet pellentesque in tempus facilisis rutrum leo, lacus nunc pretium quisque egestas habitasse. Dolor porttitor ipsum, ullamcorper metus, amet etiam euismod vitae nulla orci. Id velit quam vel lectus, molestie commodo, turpis tellus odio rhoncus vehicula ut. Et nunc vestibulum tellus et vestibulum, nunc orci ut diam nunc quam, aliquam dignissim nunc donec, aliquam class, ipsum tempus. Vestibulum proin est, vel felis, lectus nec pharetra arcu, fringilla et et nisl magna leo, lorem facilisis erat.Lorem ipsum dolor sit amet, est vel euismod et dictum fermentum integer, tortor ipsam est. Sollicitudin imperdiet fringilla placerat eros luctus facilisi, pede nunc, congue nullam dolor. Nibh neque urna neque, praesent volutpat tincidunt maecenas, scelerisque est, vitae in scelerisque placerat lacus, eu vitae lectus malesuada. Vehicula suspendisse tincidunt, aenean ac eros varius lectus quis. Orci lacus luctus nullam arcu id risus, odio feugiat turpis nullam suspendisse metus suspendisse, ligula vehicula nec fermentum ligula, convallis ultrices cras nibh eu. Leo pede iaculis mus risus, proin aliquam phasellus dui pretium arcu, pede fringilla risus, tempus odio sem lobortis lectus sem enim, laoreet donec posuere. Tempus elit vel arcu. A iaculis. A amet felis, sed sit metus. Quis etiam vitae at ipsum, et nam a. In auctor molestie suscipit enim ultrices tincidunt, nullam mi, hendrerit integer quisque elementum nonummy, enim pede magna, dui at dignissim vestibulum molestie et. Vel mattis aliquet, nulla nostra laoreet et ultrices, luctus luctus tortor libero augue orci id.
--Ante proin aenean sit elit, vel at donec lobortis eget, erat curabitur sed tempus enim, et et mollis sed in ultricies ultricies, rutrum alias porttitor erat. Convallis in voluptatum a a. Nunc odio cras ut consequat neque, in dolor nec, suspendisse et a cras consectetuer ut, in sagittis in dis blandit sit nisl, eros consequat. Arcu enim pede mattis adipiscing wisi facilisi, adipiscing morbi integer ante auctor. Porttitor lectus scelerisque pellentesque torquent, viverra donec enim. Quam vehicula sed eu, viverra dolor et sed mollis in, vulputate integer tristique elit tellus laoreet aut, sed dis adipiscing fames integer turpis, curabitur tellus velit nonummy et nam.
--
--Elit dolor maecenas vestibulum sodales ut, molestie luctus proin sit dolor mauris. In a lectus arcu, ut dui, nec molestie wisi tempus urna. Mollis imperdiet in lectus justo, pede justo nec vulputate commodo eget tincidunt, sapien tellus volutpat lacinia lectus. Ut dis tellus neque ac at sapien, ultrices vivamus bibendum mattis. Dui quisque, sed vivamus accumsan pellentesque, est donec sem. Tincidunt dignissim, vivamus aliquam lacinia neque, est integer. Turpis habitant id tempus vestibulum. Purus massa feugiat at ut massa varius, vivamus diam hendrerit tincidunt.
--
--Vitae mi fermentum a nec vehicula imperdiet, ipsum potenti suspendisse ipsum porta turpis, nam maecenas. Velit nulla a consectetuer arcu accumsan vitae, sodales cras in vitae leo eu, aliquet pellentesque in tempus facilisis rutrum leo, lacus nunc pretium quisque egestas habitasse. Dolor porttitor ipsum, ullamcorper metus, amet etiam euismod vitae nulla orci. Id velit quam vel lectus, molestie commodo, turpis tellus odio rhoncus vehicula ut. Et nunc vestibulum tellus et vestibulum, nunc orci ut diam nunc quam, aliquam dignissim nunc donec, aliquam class, ipsum tempus. Vestibulum proin est, vel felis, lectus nec pharetra arcu, fringilla et et nisl magna leo, lorem facilisis erat.
-diff -urN mustache4dart.orig/test/mustache_all.dart mustache4dart/test/mustache_all.dart
---- mustache4dart.orig/test/mustache_all.dart 2018-08-07 12:33:43.842260033 -0700
-+++ mustache4dart/test/mustache_all.dart 1969-12-31 16:00:00.000000000 -0800
-@@ -1,15 +0,0 @@
--import "mustache_context_test.dart" as context_test;
--import "mustache_issues_test.dart" as issues_test;
--import "mustache_line_test.dart" as line_test;
--import "mustache_specs_test.dart" as specs_test;
--import "mustache_test.dart" as general_test;
--import "mustache_context_reflect_test.dart" as reflect_test;
--
--void main() {
-- context_test.main();
-- issues_test.main();
-- line_test.main();
-- specs_test.main();
-- general_test.main();
-- reflect_test.main();
--}
-diff -urN mustache4dart.orig/test/mustache_context_reflect_test.dart mustache4dart/test/mustache_context_reflect_test.dart
---- mustache4dart.orig/test/mustache_context_reflect_test.dart 2018-08-07 12:36:38.952990405 -0700
-+++ mustache4dart/test/mustache_context_reflect_test.dart 1969-12-31 16:00:00.000000000 -0800
-@@ -1,170 +0,0 @@
--import 'dart:mirrors' as mirrors;
--import 'package:test/test.dart';
--import 'package:mustache4dart/src/mirrors.dart';
--
--@mirrors.MirrorsUsed()
--class Person {
-- final String name;
-- final String lastname;
-- final Person parent;
--
-- Person(this.name, {this.lastname: null, this.parent: null});
--
-- get fullname {
-- return "$name $lastname";
-- }
--
-- getFullnameWithInitial() {
-- final initial = this.parent.name[0].toUpperCase();
-- return "$name $initial. $lastname";
-- }
--}
--
--class ClassWithLambda {
-- final int num;
--
-- ClassWithLambda(this.num);
--
-- lambdaWithArity1(str) => "[[$str $num]]";
--}
--
--@mirrors.MirrorsUsed()
--class ClassWithBrackets {
-- operator [](String input) {
-- if (input == 'nullval') {
-- return null;
-- }
-- return new Person(input);
-- }
--}
--
--void main() {
-- group('reflect', () {
-- test('returns a mirror object', () {
-- final cat = new Person("cat");
-- expect(reflect(cat), isNotNull);
-- });
--
-- group('field([name])', () {
-- test('should return an object', () {
-- final cat = new Person("cat");
--
-- final actual = reflect(cat).field('name');
--
-- expect(actual, isNotNull);
-- expect(actual, new isInstanceOf());
-- });
--
-- group(".exists", () {
-- final cat = new Person("cat");
--
-- test('returns true if the field exists', () {
-- expect(reflect(cat).field('name').exists, isTrue);
-- });
--
-- test('returns true if the getter exists', () {
-- expect(reflect(cat).field('fullname').exists, isTrue);
-- });
--
-- test('returns false if the method does not exist', () {
-- expect(reflect(cat).field('fullnameWithInitial').exists, isFalse);
-- });
--
-- test('returns false if no field exists', () {
-- expect(reflect(cat).field('xyz').exists, isFalse);
-- });
--
-- test('returns false if [] operator returns a null value', () {
-- expect(reflect(new ClassWithBrackets()).field('nullval').exists,
-- isFalse);
-- });
--
-- test('returns true for map containing a field with a null value', () {
-- expect(reflect({'a': null}).field('a').exists, isTrue);
-- });
-- });
--
-- group(".val()", () {
-- test('returns the value of a field', () {
-- final cat = new Person("cat");
--
-- final actual = reflect(cat);
--
-- expect(actual.field('name').val(), "cat");
-- });
--
-- test('returns the value of a getter', () {
-- final george = new Person("George", lastname: "Valotasios");
--
-- final actual = reflect(george);
--
-- expect(actual.field('fullname').val(), "George Valotasios");
-- });
--
-- test('does not returns the value of a get methods', () {
-- final george = new Person("George",
-- lastname: "Valotasios", parent: new Person("Thomas"));
--
-- final actual = reflect(george);
--
-- expect(actual.field('fullnameWithInitial').exists, isFalse);
-- });
--
-- test('returns the value from a [] operator', () {
-- final object = new ClassWithBrackets();
--
-- final actual = reflect(object).field('xyz');
--
-- expect(actual.val(), isNotNull);
-- expect(actual.val(), new isInstanceOf());
-- expect(actual.val().name, 'xyz');
-- }, onPlatform: {
-- "js": new Skip("[] operator can not be reflected in javascript")
-- });
--
-- test('returns always a reference to the value', () {
-- final thomas = new Person("Thomas");
-- final george =
-- new Person("George", lastname: "Valotasios", parent: thomas);
--
-- final actual = reflect(george);
--
-- expect(actual.field('parent').val(), thomas);
-- });
--
-- test('returns a ref to the function if it has an arity of 1', () {
-- final labmbda = new ClassWithLambda(1);
--
-- final actual = reflect(labmbda).field('lambdaWithArity1');
--
-- expect(actual.val(), new isInstanceOf());
-- expect(actual.val()("-"), "[[- 1]]");
-- });
-- });
-- });
--
-- test('does not use reflection with Maps', () {
-- final reflection = reflect({'name': "g"});
-- expect(reflection, isNot(new isInstanceOf()));
-- });
--
-- group('with useMirrors = false', () {
-- test('should be disabled by default', () {
-- expect(USE_MIRRORS, true);
-- });
--
-- test('should return the result of the [] operator', () {
-- final reflection = reflect(new ClassWithBrackets(), useMirrors: false);
-- final value = reflection.field('George').val();
-- expect(value, new isInstanceOf());
-- expect(value.name, 'George');
-- });
--
-- test('should not be able to analyze classes with reflectioon', () {
-- final george = new Person('George');
-- final reflection = reflect(george, useMirrors: false);
-- expect(reflection.field('name').exists, isFalse);
-- });
-- });
-- });
--}
-diff -urN mustache4dart.orig/test/mustache_context_test.dart mustache4dart/test/mustache_context_test.dart
---- mustache4dart.orig/test/mustache_context_test.dart 2018-08-07 12:36:38.952990405 -0700
-+++ mustache4dart/test/mustache_context_test.dart 1969-12-31 16:00:00.000000000 -0800
-@@ -1,218 +0,0 @@
--import 'dart:mirrors';
--import 'package:test/test.dart';
--import 'package:mustache4dart/mustache_context.dart';
--
--void main() {
-- group('mustache_context lib', () {
-- test('Recursion of iterable contextes', () {
-- var contextY = {'content': 'Y', 'nodes': []};
-- var contextX = {
-- 'content': 'X',
-- 'nodes': [contextY]
-- };
-- var ctx = new MustacheContext(contextX);
-- expect(ctx.field('nodes'), isNotNull);
-- expect(ctx.field('nodes') is Iterable, isTrue);
-- expect((ctx.field('nodes') as Iterable).length, 1);
-- (ctx.field('nodes') as Iterable).forEach((n) {
-- expect(n.field('content').value(), 'Y');
-- expect(n.field('nodes').length, 0);
-- });
-- });
--
-- test('Direct interpolation', () {
-- var ctx = new MustacheContext({'n1': 1, 'n2': 2.0, 's': 'some string'});
-- expect(ctx.field('n1').field('.').value(), '1');
-- expect(ctx.field('n2').field('.').value(), '2.0');
-- expect(ctx.field('s').field('.').value(), 'some string');
-- }, testOn: "vm");
--
-- test('Direct list interpolation', () {
-- var list = [1, 'two', 'three', '4'];
-- var ctx = new MustacheContext(list);
-- expect(ctx.field('.') is Iterable, isTrue);
-- });
-- });
--
-- test('Simple context with map', () {
-- var ctx = new MustacheContext({'k1': 'value1', 'k2': 'value2'});
-- expect(ctx.field('k1').value(), 'value1');
-- expect(ctx.field('k2').value(), 'value2');
-- expect(ctx.field('k3'), null);
-- });
--
-- test('Simple context with object', () {
-- var ctx = new MustacheContext(new _Person('Γιώργος', 'Βαλοτάσιος'));
-- expect(ctx.field('name').value(), 'Γιώργος');
-- expect(ctx.field('lastname').value(), 'Βαλοτάσιος');
-- expect(ctx.field('last'), null);
-- expect(ctx.field('fullname').value(), 'Γιώργος Βαλοτάσιος');
-- expect(ctx.field('reversedName'), null);
-- expect(ctx.field('reversedLastName').value(), 'ςοισάτολαΒ');
-- });
--
-- test('Simple map with list of maps', () {
-- dynamic ctx = new MustacheContext({
-- 'k': [
-- {'k1': 'item1'},
-- {'k2': 'item2'},
-- {
-- 'k3': {'kk1': 'subitem1', 'kk2': 'subitem2'}
-- }
-- ]
-- });
-- expect(ctx.field('k').length, 3);
-- });
--
-- test('Map with list of lists', () {
-- var ctx = new MustacheContext({
-- 'k': [
-- {'k1': 'item1'},
-- {
-- 'k3': [
-- {'kk1': 'subitem1'},
-- {'kk2': 'subitem2'}
-- ]
-- }
-- ]
-- });
-- expect(ctx.field('k') is Iterable, isTrue);
-- expect((ctx.field('k') as Iterable).length, 2);
-- expect((ctx.field('k') as Iterable).last.field('k3').length, 2);
-- });
--
-- test('Object with iterables', () {
-- var p = new _Person('Νικόλας', 'Νικολάου');
-- p.contactInfos.add(new _ContactInfo('Address', {
-- 'Street': 'Κολοκωτρόνη',
-- 'Num': '31',
-- 'Zip': '42100',
-- 'Country': 'GR'
-- }));
-- p.contactInfos.add(new _ContactInfo('skype', 'some1'));
-- var ctx = new MustacheContext(p);
-- var contactInfos = ctx.field('contactInfos');
-- expect(contactInfos is Iterable, isTrue);
-- var iterableContactInfos = contactInfos as Iterable;
-- expect(iterableContactInfos.length, 2);
-- expect(
-- iterableContactInfos.first.field('value').field('Num').value(), '31');
-- });
--
-- test('Deep search with object', () {
-- //create our model:
-- _Person p = null;
-- for (int i = 10; i > 0; i--) {
-- p = new _Person("name$i", "lastname$i", p);
-- }
--
-- MustacheContext ctx = new MustacheContext(p);
-- expect(ctx.field('name').value(), 'name1');
-- expect(ctx.field('parent').field('lastname').value(), 'lastname2');
-- expect(ctx.field('parent').field('parent').field('fullname').value(),
-- 'name3 lastname3');
-- });
--
-- test('simple MustacheFunction value', () {
-- var t = new _Transformer();
-- var ctx = new MustacheContext(t);
-- var f = ctx.field('transform');
--
-- expect(f.isLambda, true);
-- expect(f.value('123 456 777'), t.transform('123 456 777'));
-- });
--
-- test('MustacheFunction from anonymus function', () {
-- var map = {'transform': (String val) => "$val!"};
-- var ctx = new MustacheContext(map);
-- var f = ctx.field('transform');
--
-- expect(f.isLambda, true);
-- expect(f.value('woh'), 'woh!');
-- });
--
-- test('Dotted names', () {
-- var ctx =
-- new MustacheContext({'person': new _Person('George', 'Valotasios')});
-- expect(ctx.field('person.name').value(), 'George');
-- });
--
-- test('Context with another context', () {
-- var ctx = new MustacheContext(new _Person('George', 'Valotasios'),
-- parent: new MustacheContext({
-- 'a': {'one': 1},
-- 'b': {'two': 2}
-- }));
-- expect(ctx.field('name').value(), 'George');
-- expect(ctx.field('a').field('one').value(), '1');
-- expect(ctx.field('b.two').value(), '2');
-- });
--
-- test('Deep subcontext test', () {
-- var map = {
-- 'a': {'one': 1},
-- 'b': {'two': 2},
-- 'c': {'three': 3}
-- };
-- var ctx = new MustacheContext({
-- 'a': {'one': 1},
-- 'b': {'two': 2},
-- 'c': {'three': 3}
-- });
-- expect(ctx.field('a'), isNotNull,
-- reason: "a should exists when using $map");
-- expect(ctx.field('a').field('one').value(), '1');
-- expect(ctx.field('a').field('two'), isNull);
-- expect(ctx.field('a').field('b'), isNotNull,
-- reason: "a.b should exists when using $map");
-- expect(ctx.field('a').field('b').field('one').value(), '1',
-- reason: "a.b.one == a.own when using $map");
-- expect(ctx.field('a').field('b').field('two').value(), '2',
-- reason: "a.b.two == b.two when using $map");
-- expect(ctx.field('a').field('b').field('three'), isNull);
-- expect(ctx.field('a').field('b').field('c'), isNotNull,
-- reason: "a.b.c should not be null when using $map");
--
-- var abc = ctx.field('a').field('b').field('c');
-- expect(abc.field('one').value(), '1',
-- reason: "a.b.c.one == a.one when using $map");
-- expect(abc.field('two').value(), '2',
-- reason: "a.b.c.two == b.two when using $map");
-- expect(abc.field('three').value(), '3');
-- });
--}
--
--@MirrorsUsed()
--class _Person {
-- final name;
-- final lastname;
-- final _Person parent;
-- List<_ContactInfo> contactInfos = [];
--
-- _Person(this.name, this.lastname, [this.parent = null]);
--
-- get fullname => "$name $lastname";
--
-- static _reverse(String str) {
-- StringBuffer out = new StringBuffer();
-- for (int i = str.length; i > 0; i--) {
-- out.write(str[i - 1]);
-- }
-- return out.toString();
-- }
--
-- reversedLastName() => _reverse(lastname);
--}
--
--@MirrorsUsed()
--class _ContactInfo {
-- final String type;
-- final value;
--
-- _ContactInfo(this.type, this.value);
--}
--
--@MirrorsUsed()
--class _Transformer {
-- String transform(String val) => "$val";
--}
-diff -urN mustache4dart.orig/test/mustache_issues_test.dart mustache4dart/test/mustache_issues_test.dart
---- mustache4dart.orig/test/mustache_issues_test.dart 2018-08-07 12:36:38.952990405 -0700
-+++ mustache4dart/test/mustache_issues_test.dart 1969-12-31 16:00:00.000000000 -0800
-@@ -1,173 +0,0 @@
--import 'dart:io';
--import 'dart:convert';
--import 'package:test/test.dart';
--import 'package:mustache4dart/mustache4dart.dart';
--import 'package:mustache4dart/mustache_context.dart';
--
--class A {
-- final bar = 'bar';
--
-- String get foo => 'foo';
--}
--
--class B extends A {}
--
--class Parent {
-- String foo;
--}
--
--class Child extends Parent {
-- List children = [];
--}
--
--class OtherChild extends Parent {}
--
--void main() {
-- group('mustache4dart issues', () {
-- test(
-- '#9: use empty strings for non existing variable',
-- () => expect(
-- render("{{#sec}}[{{variable}}]{{/sec}}", {'sec': 42}), '[]'));
--
-- test('#10',
-- () => expect(render('|\n{{#bob}}\n{{/bob}}\n|', {'bob': []}), '|\n|'));
--
-- test(
-- '#11',
-- () => expect(
-- () => render("{{#sec}}[{{var}}]{{/somethingelse}}", {'sec': 42}),
-- throwsFormatException));
--
-- test('#12: Write to a StringSink', () {
-- StringSink out = new StringBuffer();
-- StringSink outcome = render("{{name}}!", {'name': "George"}, out: out);
-- expect(out, outcome);
-- expect(out.toString(), "George!");
-- });
--
-- group('#16', () {
-- test('side effect',
-- () => expect(render('{{^x}}x{{/x}}!!!', null), 'x!!!'));
--
-- test(
-- 'root cause: For null objects the value of any property should be null',
-- () {
-- var ctx = new MustacheContext(null);
-- expect(ctx.field('xxx'), null);
-- expect(ctx.field('123'), null);
-- expect(ctx.field(''), null);
-- expect(ctx.field(null), null);
-- });
-- });
--
-- group('#17', () {
-- test(
-- 'side effect',
-- () => expect(
-- render('{{#a}}[{{{a}}}|{{b}}]{{/a}}', {'a': 'aa', 'b': 'bb'}),
-- '[aa|bb]'));
--
-- test('root cause: setting the same context as a subcontext', () {
-- final ctx = new MustacheContext({'a': 'aa', 'b': 'bb'});
-- expect(ctx, isNotNull);
-- expect(ctx.field('a').toString(), isNotNull);
--
-- //Here lies a problem if the subaa.other == suba
-- expect(ctx.field('a').field('a').toString(), isNotNull);
-- });
-- });
--
-- test('#20', () {
-- var currentPath = Directory.current.path;
-- if (!currentPath.endsWith('/test')) {
-- currentPath = "$currentPath/test";
-- }
-- final template = new File("$currentPath/lorem-ipsum.txt")
-- .readAsStringSync(encoding: UTF8);
--
-- final String out = render(template, {'ma': 'ma'});
-- expect(out, template);
-- }, onPlatform: {"js": new Skip("io is not available on a browser")});
--
-- test('#25', () {
-- var ctx = {
-- "parent_name": "John",
-- "children": [
-- {"name": "child"}
-- ]
-- };
-- expect(render('{{#children}}Parent: {{parent_name}}{{/children}}', ctx),
-- 'Parent: John');
-- });
--
-- test('#28', () {
-- var model = {
-- "name": "God",
-- "hasChildren": true,
-- "children": [
-- {"name": "granpa", "hasChildren": true},
-- {"name": "granma", "hasChildren": false}
-- ]
-- };
--
-- expect(
-- render(
-- '{{#children}}{{name}}{{#hasChildren}} has children{{/hasChildren}},{{/children}}',
-- model),
-- 'granpa has children,granma,');
-- });
--
-- test('#29', () {
-- var list = [1, 'two', 'three', '4'];
-- expect(render('{{#.}}{{.}},{{/.}}', list), '1,two,three,4,');
-- });
--
-- test('#30', () {
-- final txt = '''
--
--
--
Hello World!
--
--
--''';
-- expect(render(txt, null), txt);
-- });
--
-- test('#33', () {
-- final b = new B();
-- expect(render('{{b.foo}}', {'b': b}), 'foo');
-- expect(render('{{b.bar}}', {'b': b}), 'bar');
-- });
--
-- test(
-- '#41 do not look into parent context if current context has field but its value is null',
-- () {
-- var c = new Child()
-- ..foo = 'child'
-- ..children = [
-- new OtherChild()..foo = 'otherchild',
-- new OtherChild()..foo = null
-- ];
--
-- var template = '''
--{{foo}}
--{{#children}}{{foo}}!{{/children}}''';
--
-- var output = render(template, c, assumeNullNonExistingProperty: false);
-- var expected = "child\notherchild!!";
--
-- expect(output, expected);
-- });
--
-- test('#44 should provide a way to check for non empty lists', () {
-- final map = {
-- 'list': [1, 2]
-- };
-- expect(
-- render(
-- '{{^list.empty}}