Git Product home page Git Product logo

morestachio's Issues

Interface generics matching in `MorestachioFormatterService`

Is your feature request related to a problem? Please describe.
Currently the MorestachioFormatterService is not capable of matching generic interfaces like

IEnumerable<T> assignable from IList<T>

Describe the solution you'd like
It should be possible to check if thoses interfaces can match maybe including matching of generic types like IDictionary<TKey,TValue> from Dictionary<TKey, TValue> via the Type.GetGenericTypeDefinition

using "#if" with a formatter as a condition

When using an if Statement with a Formatter the result of the evaluation is used as the current Scope.
For example:
Given is a custom formatter like:

[MorestachioFormatter("TestFormatter(", "XXX")]
public static bool TestFormatter(object originalObject)
{
	return true;
}

When this formatter is used as a condition:

{{#if .("TestFormatter")}}
{{.}}
{{/If}}

=> Results in "true", but the expected result is the representation of the current scope before the if.

If a regular path is used everything works as expected:

{{#If root.Istrue}}
{{.}}
{{/If}}

=> Results in the the representation of the current scope before the if

MorestachioFormatterService is not thread safe

Describe the bug
The MorestachioFormatterService is not thread safe.

To Reproduce

XXX threw exception: 
System.TypeInitializationException: The type initializer for 'Morestachio.Formatter.Framework.MorestachioFormatterService' threw an exception. ---> System.TypeInitializationException: The type initializer for 'Morestachio.Formatter.Predefined.Accounting.CurrencyHandler' threw an exception. ---> System.ArgumentException: An item with the same key has already been added. Key: PYG
  Stack Trace:
      at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at Morestachio.Formatter.Predefined.Accounting.CurrencyHandler..cctor()
--- End of inner exception stack trace ---
    at Morestachio.Formatter.Predefined.Accounting.CurrencyHandler.get_DefaultHandler()
   at Morestachio.Formatter.Framework.MorestachioFormatterService..cctor()
--- End of inner exception stack trace ---
    at Morestachio.Formatter.Framework.MorestachioFormatterService..ctor(Boolean useCache)
   at Morestachio.ParserOptions..ctor(ITemplateContainer template, Func`2 sourceStream, Encoding encoding)
   at Morestachio.ParserOptions..ctor(ITemplateContainer template, Func`1 sourceStream, Encoding encoding)
   at Morestachio.ParserOptions..ctor(String template, Func`1 sourceStream, Encoding encoding)
   at Morestachio.ParserOptions..ctor(String template, Func`1 sourceStream)
   at Morestachio.ParserOptions..ctor(String template)

Expected behavior
Should use thread safe collections internally: https://docs.microsoft.com/en-us/dotnet/standard/collections/thread-safe/

Formatter Results as Arguments

Hi,
using the result of a Formatter Call as an argument for another Formatter call raises an Exception.
As soon as the result of the first Formatter is stored in a Variable everything works as expected.

This test should cover the scenario:

[Test]
public void TestMethodAsArgumentAccess()
{
	var options = new ParserOptions("{{data.Multiply(data.Multiply(data))}}", null, DefaultEncoding);
	options.Formatters.AddFromType(typeof(NumberFormatter));
	var template = Parser.ParseWithOptions(options);
	var andStringify = template.CreateAndStringify(new Dictionary<string, object>()
	{
		{"data", 2}
	});

	Assert.That(andStringify, Is.EqualTo("8"));
}

public static class NumberFormatter
{
	[MorestachioFormatter("Multiply", "XXX")]
	public static decimal Multiply(object value, object value2)
	{
		decimal a = 0;
		decimal.TryParse(value.ToString(), out a);
		decimal b = 0;
		decimal.TryParse(value2.ToString(), out b);
		return a * b;
	}
}

Operators cannot parse when there is a string at the left hand of the operator

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. What class
  2. What input
  3. What Environment

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Version [e.g. 22]
  • Got code from
  • CodeProject
  • Nuget
  • Github
  • Elsewhere (please define)

Additional context
Add any other context about the problem here.

Inline whitespace control not always renders correctly

Describe the bug
When using the ToParsableStringDocumentVisitor to render an document where one token contains the |- whitespace operator the operator is not always rendered when on root.

To Reproduce
as seen in ParserCanVariableScope test

CurrencyHandler duplicate keys in Currencies dictionary causes exception

Describe the bug
In class CurrencyHandler the use of ISOCurrencySymbol for the key to the dictionary DefaultHandler.Currencies causes an exception due to duplicates, and Morestachio cannot be instantiated. The same issue had an attempted fix with #21

To Reproduce
Steps to reproduce the behavior:

  1. Class CurrencyHandler
  2. Cultures from a Windows 2012 Server (see list of LCIDs/Cultures)
  3. Windows 2012 Server

Expected behavior
That when attempting to populate the Dictionary for DefaultHandler.Currencies any duplicate ISOCurrencySymbols do not cause an exception and Morestachio can be instantiated.

Screenshots
See the report here, we get exactly the same exception: #21

Desktop (please complete the following information):

  • OS: Windows 2012
  • Windows Server 2012 R2 Standard (64Bit) 9600 (Xen)
  • Got code from Nuget and Github (got the CurrencyHandler from the master branch to test on affected servers)

Additional context
The problem is only occurring on two servers we have out of dozens, so the problem is clearly server configuration related. I have attached here a file with the LCIDs and Culture object properties from one of the servers that the instantiation fails on. I believe that the problem is that the Linq query to populate DefaultHandler.Currencies does not omit duplicate ISOCurrencySymbols when grouping by LCID and CurrencyEnglishName (lines 17 through 33 in CurrencyHandler.cs).

LCID.csv

Thanks in advance! Joe

Unary Operators in expressions cannot parse other operators on right hand

Describe the bug
Assume an expression like this:
e > 5 && e < 8
The ExpressionParser will parse the expression like this:
(e > 5 && e) < 8

To Reproduce

Expected behavior
Expected the parser to parse the expression like this: (e > 5) && (e < 8)

Desktop (please complete the following information):

  • OS: WIN10
  • Version 5.0.1.534
  • Got code from
  • CodeProject
  • Nuget
  • Github
  • Elsewhere (please define)

Additional context

Provide Default behaviour of "Nullable" types in plain objects when value is NULL

Hello!, I'm currently generating javascript files with a template, injecting the values with morestachio.

The Problem

Part of my template file (javascript.tpl):

 var loginBonusAmount = {{LoginBonusAmount}};

Part of my plain object (JavascriptParams.cs):

public int? LoginBonusAmount { get; set; }

Wanted output if property is NULL:

var loginBonusAmount = null;

Current output:

var loginBonusAmount = ;

The Solution

public class NullableValuesResolver : IValueResolver {
        public bool CanResolve(Type type, object value, string path, ContextObject context) {
            var propertyType = type.GetProperty(path).PropertyType;
            return Nullable.GetUnderlyingType(propertyType) != null;
        }

        public object Resolve(Type type, object value, string path, ContextObject context) {
            var result = type.GetProperty(path).GetValue(value);
            if (result == null)
            {
                return "null";
            }
            return result;
        }
    }

[...]

 var options = new ParserOptions(sourceTemplate)
 {
    ValueResolver = new NullableValuesResolver()
 };

Root Access

Hi,
retrieval of data with the ~ keyword, outside of any scope, does not return the excpected result.
Called within an each statement, or without the ~ keyword, everything is fine.

This test should cover the scenario:

[Test]
public void TestRootAccess()
{
	var templateWorking = "{{#EACH data.testList.Select()}}" +
	                      "{{#var eachValue = ~data.testInt}}" +
	                      "{{/EACH}}" +
	                      "{{eachValue}} = {{~data.testInt}} = {{data.testInt}}";

	var parsingOptionsWorking = new ParserOptions(templateWorking, null, ParserFixture.DefaultEncoding);
	parsingOptionsWorking.Formatters.AddFromType(typeof(DynamicLinq));
	parsingOptionsWorking.Formatters.AddFromType(typeof(NumberFormatter));
	var parsedTemplateWorking = Parser.ParseWithOptions(parsingOptionsWorking);

	var modelWorking = new Dictionary<string, object>()
	{
		{
			"data", new Dictionary<string, object>()
			{
				{
					"testList",
					new string[1]
					{
						string.Empty
					}
				},
				{
					"testInt",
					2
				}
			}
		}
	};
    
	var result = parsedTemplateWorking.Create(modelWorking).Stream.Stringify(true, ParserFixture.DefaultEncoding);
	Assert.AreEqual("2 = 2 = 2", result);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.