diff --git a/source/Handlebars.Test/Issues/Issue285Tests.cs b/source/Handlebars.Test/Issues/Issue285Tests.cs
new file mode 100644
index 00000000..11c28e02
--- /dev/null
+++ b/source/Handlebars.Test/Issues/Issue285Tests.cs
@@ -0,0 +1,104 @@
+using Xunit;
+
+namespace HandlebarsDotNet.Test.Issues
+{
+ ///
+ /// Regression tests for GitHub issue #285:
+ /// Support the includeZero=true hash argument on the built-in #if helper,
+ /// matching Handlebars.js behaviour (https://handlebarsjs.com/guide/builtin-helpers.html#if).
+ ///
+ public class Issue285Tests
+ {
+ [Fact]
+ public void IfWithIncludeZeroTrue_ZeroInt_RendersBlock()
+ {
+ var source = "{{#if value includeZero=true}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = 0 });
+ Assert.Equal("yes", result);
+ }
+
+ [Fact]
+ public void IfWithIncludeZeroTrue_ZeroDouble_RendersBlock()
+ {
+ var source = "{{#if value includeZero=true}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = 0.0 });
+ Assert.Equal("yes", result);
+ }
+
+ [Fact]
+ public void IfWithIncludeZeroTrue_NonZeroInt_RendersBlock()
+ {
+ var source = "{{#if value includeZero=true}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = 1 });
+ Assert.Equal("yes", result);
+ }
+
+ [Fact]
+ public void IfWithIncludeZeroFalse_ZeroInt_DoesNotRenderBlock()
+ {
+ var source = "{{#if value includeZero=false}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = 0 });
+ Assert.Equal("no", result);
+ }
+
+ [Fact]
+ public void IfWithoutIncludeZero_ZeroInt_StillTreatedAsFalsy()
+ {
+ var source = "{{#if value}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = 0 });
+ Assert.Equal("no", result);
+ }
+
+ [Fact]
+ public void IfWithIncludeZeroTrue_NullValue_StillTreatedAsFalsy()
+ {
+ var source = "{{#if value includeZero=true}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = (object)null });
+ Assert.Equal("no", result);
+ }
+
+ [Fact]
+ public void IfWithIncludeZeroTrue_EmptyString_StillTreatedAsFalsy()
+ {
+ var source = "{{#if value includeZero=true}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = string.Empty });
+ Assert.Equal("no", result);
+ }
+
+ [Fact]
+ public void IfWithIncludeZeroTrue_FalseBool_StillTreatedAsFalsy()
+ {
+ var source = "{{#if value includeZero=true}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = false });
+ Assert.Equal("no", result);
+ }
+
+ [Fact]
+ public void IfWithIncludeZeroTrue_TrueBool_RendersBlock()
+ {
+ var source = "{{#if value includeZero=true}}yes{{else}}no{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = true });
+ Assert.Equal("yes", result);
+ }
+
+ [Fact]
+ public void IfWithHashArgument_DoesNotCrash()
+ {
+ // Regression test: passing any hash arg to #if previously threw
+ // InvalidOperationException: "Sequence contains more than one element".
+ var source = "{{#if value includeZero=true}}yes{{/if}}";
+ var template = Handlebars.Compile(source);
+ var result = template(new { value = 42 });
+ Assert.Equal("yes", result);
+ }
+ }
+}
diff --git a/source/Handlebars/Compiler/Lexer/Converter/BlockAccumulators/ConditionalBlockAccumulatorContext.cs b/source/Handlebars/Compiler/Lexer/Converter/BlockAccumulators/ConditionalBlockAccumulatorContext.cs
index 297bff2e..d0b0a973 100644
--- a/source/Handlebars/Compiler/Lexer/Converter/BlockAccumulators/ConditionalBlockAccumulatorContext.cs
+++ b/source/Handlebars/Compiler/Lexer/Converter/BlockAccumulators/ConditionalBlockAccumulatorContext.cs
@@ -8,13 +8,13 @@ namespace HandlebarsDotNet.Compiler
internal class ConditionalBlockAccumulatorContext : BlockAccumulatorContext
{
private enum TestType { Direct, Reverse }
-
+
private static readonly HashSet ValidHelperNames = new HashSet { "if", "unless" };
-
+
private readonly List _conditionalBlock = new List();
private Expression _currentCondition;
private List _bodyBuffer = new List();
-
+
public sealed override string BlockName { get; protected set; }
public ConditionalBlockAccumulatorContext(Expression startingNode)
diff --git a/source/Handlebars/Compiler/Translation/Expression/BoolishConverter.cs b/source/Handlebars/Compiler/Translation/Expression/BoolishConverter.cs
index 0040dcd9..06f7bc28 100644
--- a/source/Handlebars/Compiler/Translation/Expression/BoolishConverter.cs
+++ b/source/Handlebars/Compiler/Translation/Expression/BoolishConverter.cs
@@ -30,7 +30,6 @@ protected override Expression VisitBoolishExpression(BoolishExpression bex)
var @object = Arg