Skip to content

Mustachio: Implement Property.isNullValue, renderValue; section rendering; lots of tests #2448

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
794 changes: 538 additions & 256 deletions lib/src/generator/templates.renderers.dart

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lib/src/mustachio/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class MustachioParser {
addTextNode(textStartIndex, textEndIndex);
children.add(result.node);
textStartIndex = _index;
continue;
}
}
_index++;
Expand Down
48 changes: 46 additions & 2 deletions lib/src/mustachio/renderer_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,44 @@ abstract class RendererBase<T> {
}

void section(Section node) {
// TODO(srawlins): Implement.
var key = node.key.first;
var property = getProperty(key);
if (property == null) {
if (parent == null) {
throw MustachioResolutionError(
'Failed to resolve $key as a property on any types in the current '
'context');
} else {
return parent.section(node);
}
}

if (property.getBool != null) {
var boolResult = property.getBool(context);
if ((boolResult && !node.invert) || (!boolResult && node.invert)) {
renderBlock(node.children);
}
return;
}

if (property.renderIterable != null) {
// An inverted section is rendered with the current context.
if (node.invert && property.isEmptyIterable(context)) {
renderBlock(node.children);
}
if (!node.invert && !property.isEmptyIterable(context)) {
write(property.renderIterable(context, this, node.children));
}
return;
}

// If this section is not a conditional or repeated section, it is a value
// section, regardless of type.
if (node.invert && property.isNullValue(context)) {
renderBlock(node.children);
} else if (!node.invert && !property.isNullValue(context)) {
write(property.renderValue(context, this, node.children));
}
}

void partial(Partial node) {
Expand Down Expand Up @@ -103,14 +140,21 @@ class Property<T> {
T, RendererBase<T>, List<MustachioNode> /*!*/) /*?*/
renderIterable;

final bool /*!*/ Function(T) /*?*/ isNullValue;

final String /*!*/ Function(
T, RendererBase<T>, List<MustachioNode> /*!*/) /*?*/ renderValue;

// TODO(srawlins): Add functions for rendering other properties.

Property(
{@required this.getValue,
this.getProperties,
this.getBool,
this.isEmptyIterable,
this.renderIterable});
this.renderIterable,
this.isNullValue,
this.renderValue});
}

/// An error indicating that a renderer failed to resolve a key.
Expand Down
22 changes: 13 additions & 9 deletions test/mustachio/builder_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,6 @@ class Bar {}
'static Map<String, Property<CT_>> propertyMap<CT_ extends Foo>() => {'));
});

test('with a property map with a String property', () {
expect(generatedContent, contains('''
's1': Property(
getValue: (CT_ c) => c.s1,
getProperties: _Renderer_String.propertyMap,
),
'''));
});

test('with a property map which references the superclass', () {
expect(generatedContent,
contains('..._Renderer_FooBase.propertyMap<CT_>(),'));
Expand Down Expand Up @@ -165,6 +156,19 @@ class Bar {}
return buffer.toString();
},
),
'''));
});

test('with a property map with a non-bool, non-Iterable property', () {
expect(generatedContent, contains('''
's1': Property(
getValue: (CT_ c) => c.s1,
getProperties: _Renderer_String.propertyMap,
isNullValue: (CT_ c) => c.s1 == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_String(c.s1, ast, parent: r);
},
),
'''));
});
});
Expand Down
40 changes: 40 additions & 0 deletions test/mustachio/foo.renderers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class Renderer_Foo extends RendererBase<Foo> {
's1': Property(
getValue: (CT_ c) => c.s1,
getProperties: Renderer_String.propertyMap,
isNullValue: (CT_ c) => c.s1 == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_String(c.s1, ast, parent: r);
},
),
...Renderer_Object.propertyMap<CT_>(),
};
Expand Down Expand Up @@ -82,6 +86,10 @@ class Renderer_String extends RendererBase<String> {
'hashCode': Property(
getValue: (CT_ c) => c.hashCode,
getProperties: Renderer_int.propertyMap,
isNullValue: (CT_ c) => c.hashCode == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_int(c.hashCode, ast, parent: r);
},
),
'isEmpty': Property(
getValue: (CT_ c) => c.isEmpty,
Expand All @@ -96,6 +104,10 @@ class Renderer_String extends RendererBase<String> {
'length': Property(
getValue: (CT_ c) => c.length,
getProperties: Renderer_int.propertyMap,
isNullValue: (CT_ c) => c.length == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_int(c.length, ast, parent: r);
},
),
'runes': Property(
getValue: (CT_ c) => c.runes,
Expand Down Expand Up @@ -137,6 +149,10 @@ class Renderer_Object extends RendererBase<Object> {
'hashCode': Property(
getValue: (CT_ c) => c.hashCode,
getProperties: Renderer_int.propertyMap,
isNullValue: (CT_ c) => c.hashCode == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_int(c.hashCode, ast, parent: r);
},
),
};

Expand Down Expand Up @@ -165,6 +181,10 @@ class Renderer_bool extends RendererBase<bool> {
'hashCode': Property(
getValue: (CT_ c) => c.hashCode,
getProperties: Renderer_int.propertyMap,
isNullValue: (CT_ c) => c.hashCode == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_int(c.hashCode, ast, parent: r);
},
),
...Renderer_Object.propertyMap<CT_>(),
};
Expand Down Expand Up @@ -194,6 +214,10 @@ class Renderer_List<E> extends RendererBase<List<E>> {
'length': Property(
getValue: (CT_ c) => c.length,
getProperties: Renderer_int.propertyMap,
isNullValue: (CT_ c) => c.length == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_int(c.length, ast, parent: r);
},
),
'reversed': Property(
getValue: (CT_ c) => c.reversed,
Expand Down Expand Up @@ -226,6 +250,10 @@ class Renderer_int extends RendererBase<int> {
'bitLength': Property(
getValue: (CT_ c) => c.bitLength,
getProperties: Renderer_int.propertyMap,
isNullValue: (CT_ c) => c.bitLength == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_int(c.bitLength, ast, parent: r);
},
),
'isEven': Property(
getValue: (CT_ c) => c.isEven,
Expand All @@ -240,6 +268,10 @@ class Renderer_int extends RendererBase<int> {
'sign': Property(
getValue: (CT_ c) => c.sign,
getProperties: Renderer_int.propertyMap,
isNullValue: (CT_ c) => c.sign == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_int(c.sign, ast, parent: r);
},
),
...Renderer_num.propertyMap<CT_>(),
};
Expand Down Expand Up @@ -269,6 +301,10 @@ class Renderer_num extends RendererBase<num> {
'hashCode': Property(
getValue: (CT_ c) => c.hashCode,
getProperties: Renderer_int.propertyMap,
isNullValue: (CT_ c) => c.hashCode == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_int(c.hashCode, ast, parent: r);
},
),
'isFinite': Property(
getValue: (CT_ c) => c.isFinite,
Expand All @@ -293,6 +329,10 @@ class Renderer_num extends RendererBase<num> {
'sign': Property(
getValue: (CT_ c) => c.sign,
getProperties: Renderer_num.propertyMap,
isNullValue: (CT_ c) => c.sign == null,
renderValue: (CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
return _render_num(c.sign, ast, parent: r);
},
),
...Renderer_Object.propertyMap<CT_>(),
};
Expand Down
11 changes: 11 additions & 0 deletions test/mustachio/parser_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,17 @@ void main() {
expect(section.children, isEmpty);
});

test('parses section with variable tag inside', () {
var parser = MustachioParser('Text {{#key}}{{two}}{{/key}}');
var ast = parser.parse();
expect(ast, hasLength(2));
_expectText(ast[0], equals('Text '));
var section = ast[1] as Section;
_expectSection(section, equals(['key']));
expect(section.children, hasLength(1));
_expectVariable(section.children.single, equals(['two']));
});

test('parses section with empty key as text', () {
var parser = MustachioParser('Text {{#}}{{/key}}');
var ast = parser.parse();
Expand Down
Loading