Example #1
0
        public void String_ToNumber_ParsesNumber()
        {
            var value  = StringValue.Create("0.1357") as IValue;
            var result = value.ImplicitConversionToNumberValue();

            Assert.AreEqual(0.1357M, result.Value);
        }
Example #2
0
        public void StringEmpty_ToBool_IsFalse()
        {
            var value  = StringValue.Create("") as IValue;
            var result = value.ImplicitConversionToBoolValue();

            Assert.AreEqual(false, result.Value);
        }
Example #3
0
        public void StringNonEmpty_ToBool_IsTrue()
        {
            var value  = StringValue.Create("x") as IValue;
            var result = value.ImplicitConversionToBoolValue();

            Assert.AreEqual(true, result.Value);
        }
Example #4
0
        public ValueTask <FluidValue> ProcessAsync(FluidValue input, FilterArguments arguments, TemplateContext context)
        {
            switch (input.Type)
            {
            case FluidValues.Array:
                return(new ValueTask <FluidValue>(new StringValue(JsonConvert.SerializeObject(input.Enumerate().Select(o => o.ToObjectValue())))));

            case FluidValues.Boolean:
                return(new ValueTask <FluidValue>(new StringValue(JsonConvert.SerializeObject(input.ToBooleanValue()))));

            case FluidValues.Nil:
                return(new ValueTask <FluidValue>(StringValue.Create("null")));

            case FluidValues.Number:
                return(new ValueTask <FluidValue>(new StringValue(JsonConvert.SerializeObject(input.ToNumberValue()))));

            case FluidValues.DateTime:
            case FluidValues.Dictionary:
            case FluidValues.Object:
                return(new ValueTask <FluidValue>(new StringValue(JsonConvert.SerializeObject(input.ToObjectValue()))));

            case FluidValues.String:
                var stringValue = input.ToStringValue();

                if (string.IsNullOrWhiteSpace(stringValue))
                {
                    return(new ValueTask <FluidValue>(input));
                }

                return(new ValueTask <FluidValue>(new StringValue(JsonConvert.SerializeObject(stringValue))));
            }

            throw new NotSupportedException("Unrecognized FluidValue");
        }
Example #5
0
        public void String_ToString_IsSameValue()
        {
            var value  = StringValue.Create("V?") as IValue;
            var result = value.ImplicitConversionToStringValue();

            Assert.AreEqual("V?", result.Value);
        }
Example #6
0
        public static FluidValue Json(FluidValue input, FilterArguments arguments, TemplateContext context)
        {
            var options = new JsonSerializerOptions
            {
                WriteIndented = arguments.At(0).ToBooleanValue()
            };

            switch (input.Type)
            {
            case FluidValues.Array:
                return(new StringValue(JsonSerializer.Serialize(input.Enumerate().Select(o => o.ToObjectValue()), options)));

            case FluidValues.Boolean:
                return(new StringValue(JsonSerializer.Serialize(input.ToBooleanValue(), options)));

            case FluidValues.Nil:
                return(StringValue.Create("null"));

            case FluidValues.Number:
                return(new StringValue(JsonSerializer.Serialize(input.ToNumberValue(), options)));

            case FluidValues.DateTime:
            case FluidValues.Dictionary:
            case FluidValues.Object:
                return(new StringValue(JsonSerializer.Serialize(input.ToObjectValue(), options)));

            case FluidValues.String:
                return(new StringValue(JsonSerializer.Serialize(input.ToStringValue(), options)));
            }

            throw new NotSupportedException("Unrecognized FluidValue");
        }
Example #7
0
        /// <summary>
        /// Redefines the True/False keywords to be case-insensitive.
        /// </summary>
        private void DefineLavaTrueFalseAsCaseInsensitive()
        {
            // To redefine the True and False parsers, we need to rebuild the Fluid Primary expression parser.
            // Fluid defines a Primary expression as: primary => NUMBER | STRING | BOOLEAN | MEMBER

            // Reproduce the standard Fluid parsers that are internally defined by the default parser.
            var indexer = Between(LBracket, Primary, RBracket).Then <MemberSegment>(x => new IndexerSegment(x));

            var member = Identifier.Then <MemberSegment>(x => new IdentifierSegment(x)).And(
                ZeroOrMany(
                    Dot.SkipAnd(Identifier.Then <MemberSegment>(x => new IdentifierSegment(x)))
                    .Or(indexer)))
                         .Then(x =>
            {
                x.Item2.Insert(0, x.Item1);
                return(new MemberExpression(x.Item2));
            });

            // Redefine the Fluid keywords "true" and "false" as case-insensitive.
            var trueParser  = Terms.Text("true", caseInsensitive: true);
            var falseParser = Terms.Text("false", caseInsensitive: true);

            // Replace the default definition of the Fluid Primary parser.
            Primary.Parser = Number.Then <Expression>(x => new LiteralExpression(NumberValue.Create(x)))
                             .Or(String.Then <Expression>(x => new LiteralExpression(StringValue.Create(x.ToString()))))
                             .Or(trueParser.Then <Expression>(x => new LiteralExpression(BooleanValue.True)))
                             .Or(falseParser.Then <Expression>(x => new LiteralExpression(BooleanValue.False)))
                             .Or(member.Then <Expression>(x => x));
        }
Example #8
0
        public static ValueTask <FluidValue> Split(FluidValue input, FilterArguments arguments, TemplateContext context)
        {
            string[] strings;

            var stringInput = input.ToStringValue();
            var separator   = arguments.At(0).ToStringValue();

            if (separator == "")
            {
                strings = new string[stringInput.Length];

                for (var i = 0; i < stringInput.Length; i++)
                {
                    strings[i] = stringInput[i].ToString();
                }
            }
            else
            {
                strings = stringInput.Split(separator, StringSplitOptions.RemoveEmptyEntries);
            }

            var values = new FluidValue[strings.Length];

            for (var i = 0; i < strings.Length; i++)
            {
                values[i] = StringValue.Create(strings[i]);
            }

            return(new ArrayValue(values));
        }
Example #9
0
        public void StringNonNumber_ToNumber_IsZero()
        {
            var value  = StringValue.Create("Bob") as IValue;
            var result = value.ImplicitConversionToNumberValue();

            Assert.AreEqual(0, result.Value);
        }
Example #10
0
        public override Value GetValue(UserItem item)
        {
            if (item.Item is Movie)
            {
                return(StringValue.Create(item.Item.Name));
            }

            return(Value.None);
        }
Example #11
0
        public override Value GetValue(UserItem item)
        {
            if (item.Item is Audio audio)
            {
                return(StringValue.Create(audio.Album));
            }

            return(Value.None);
        }
Example #12
0
        public override Value GetValue(UserItem item)
        {
            if (item.Item is Episode episode)
            {
                return(StringValue.Create(episode.SeriesName));
            }

            return(Value.None);
        }
Example #13
0
 public Task <BaseValue> GetFiles(string directoryPath) => this.Execute(
     Bridge.File.GetFiles(directoryPath),
     files =>
 {
     int i = 1;
     return(new ArrayValue(files.ToDictionary(
                               value => (i++).ToString(CultureInfo.CurrentCulture),
                               value => StringValue.Create(value))));
 });
Example #14
0
        public void MinusWithDecimalPointFromObject(string input, string argument, decimal expectedResult)
        {
            var inputA  = NumberValue.Create(input);
            var inputB  = new FilterArguments(StringValue.Create(argument));
            var context = new TemplateContext();

            var result = NumberFilters.Minus(inputA, inputB, context);

            Assert.Equal(expectedResult, result.Result.ToNumberValue());
        }
Example #15
0
        /// <summary>
        /// Redefines the True/False keywords to be case-insensitive.
        /// </summary>
        private void DefineLavaTrueFalseAsCaseInsensitive()
        {
            // To redefine the True and False parsers, we need to rebuild the Fluid Primary expression parser.
            // Fluid defines a Primary expression as: primary => STRING | BOOLEAN | EMPTY | MEMBER | NUMBER.

            // Reproduce the standard Fluid parsers that are internally defined by the default parser.
            var integer = Terms.Integer().Then <Expression>(x => new LiteralExpression(NumberValue.Create(x)));

            var indexer = Between(LBracket, Primary, RBracket).Then <MemberSegment>(x => new IndexerSegment(x));

            var member = Identifier.Then <MemberSegment>(x => new IdentifierSegment(x)).And(
                ZeroOrMany(
                    Dot.SkipAnd(Identifier.Then <MemberSegment>(x => new IdentifierSegment(x)))
                    .Or(indexer)))
                         .Then(x =>
            {
                x.Item2.Insert(0, x.Item1);
                return(new MemberExpression(x.Item2));
            });

            var range = LParen
                        .SkipAnd(OneOf(integer, member.Then <Expression>(x => x)))
                        .AndSkip(Terms.Text(".."))
                        .And(OneOf(integer, member.Then <Expression>(x => x)))
                        .AndSkip(RParen)
                        .Then <Expression>(x => new RangeExpression(x.Item1, x.Item2));

            Primary.Parser =
                String.Then <Expression>(x => new LiteralExpression(StringValue.Create(x.ToString())))
                .Or(member.Then <Expression>(x => {
                if (x.Segments.Count == 1)
                {
                    // Redefine these Liquid keywords as case-insensitive for compatibility with Lava.
                    switch ((x.Segments[0] as IdentifierSegment).Identifier.ToLower())
                    {
                    case "empty":
                        return(EmptyKeyword);

                    case "blank":
                        return(BlankKeyword);

                    case "true":
                        return(TrueKeyword);

                    case "false":
                        return(FalseKeyword);
                    }
                }

                return(x);
            }))
                .Or(Number.Then <Expression>(x => new LiteralExpression(NumberValue.Create(x))))
                .Or(range);
        }
Example #16
0
 public BaseValue GetValue(string arrayName, string index)
 {
     if (this.arrays.TryGetValue(arrayName, out ArrayValue array) && array.TryGetValue(index, out BaseValue value))
     {
         return(value);
     }
     else
     {
         return(StringValue.Create(string.Empty));
     }
 }
Example #17
0
        public void Plus()
        {
            var input = NumberValue.Create(6);

            var arguments = new FilterArguments(StringValue.Create("3"));
            var context   = new TemplateContext();

            var result = NumberFilters.Plus(input, arguments, context);

            Assert.Equal(9, result.Result.ToNumberValue());
        }
Example #18
0
        public async Task NoTimeZoneIsParsedAsLocal()
        {
            var input   = StringValue.Create("1970-01-01 00:00:00");
            var format  = new FilterArguments(new StringValue("%a %b %e %H:%M:%S %Y %z"));
            var context = new TemplateContext {
                TimeZone = Pacific
            };

            var result = await MiscFilters.Date(input, format, context);

            Assert.Equal("Thu Jan  1 00:00:00 1970 -0800", result.ToStringValue());
        }
Example #19
0
        public override bool TryParse(string value, out Value val)
        {
            val = null;
            var match = ParseRegEx.Match(value);

            if (match.Success)
            {
                val = StringValue.Create(match.Groups[1].Value);
                return(true);
            }

            return(false);
        }
Example #20
0
        public async Task DefaultTimeZoneIsSetWhenNotParsed()
        {
            // This test ensures that when a TZ is specified it uses it instead of the settings one
            var input = StringValue.Create("1970-01-01 00:00:00");

            var format  = new FilterArguments(new StringValue("%s"));
            var context = new TemplateContext {
                TimeZone = Eastern
            };

            var result = await MiscFilters.Date(input, format, context);

            Assert.Equal("18000", result.ToStringValue());
        }
Example #21
0
        private async Task <BaseValue> Execute <T>(Task <FileBridgeModels.Result <T> > action, Func <T, BaseValue> converter)
        {
            var result = await action.ConfigureAwait(false);

            if (result.Success)
            {
                this.lastError = string.Empty;
                return(converter(result.Value));
            }
            else
            {
                this.lastError = result.Error;
                return(StringValue.Create(FailedResponse));
            }
        }
Example #22
0
 public IValue Evaluate()
 {
     if (Operator == "+")
     {
         return(NumberValue.Create(Left.Evaluate().ImplicitConversionToNumberValue().Value + Right.Evaluate().ImplicitConversionToNumberValue().Value));
     }
     if (Operator == "-")
     {
         return(NumberValue.Create(Left.Evaluate().ImplicitConversionToNumberValue().Value - Right.Evaluate().ImplicitConversionToNumberValue().Value));
     }
     if (Operator == "*")
     {
         return(NumberValue.Create(Left.Evaluate().ImplicitConversionToNumberValue().Value *Right.Evaluate().ImplicitConversionToNumberValue().Value));
     }
     if (Operator == "/")
     {
         return(NumberValue.Create(Left.Evaluate().ImplicitConversionToNumberValue().Value / Right.Evaluate().ImplicitConversionToNumberValue().Value));
     }
     if (Operator == "%")
     {
         return(NumberValue.Create(Left.Evaluate().ImplicitConversionToNumberValue().Value % Right.Evaluate().ImplicitConversionToNumberValue().Value));
     }
     if (Operator == "@&")
     {
         return(NumberValue.Create(Left.Evaluate().ImplicitConversionToNumberValue().BitwiseValue & Right.Evaluate().ImplicitConversionToNumberValue().BitwiseValue));
     }
     if (Operator == "@|")
     {
         return(NumberValue.Create(Left.Evaluate().ImplicitConversionToNumberValue().BitwiseValue | Right.Evaluate().ImplicitConversionToNumberValue().BitwiseValue));
     }
     if (Operator == "@^")
     {
         return(NumberValue.Create(Left.Evaluate().ImplicitConversionToNumberValue().BitwiseValue ^ Right.Evaluate().ImplicitConversionToNumberValue().BitwiseValue));
     }
     if (Operator == "&")
     {
         return(StringValue.Create(Left.Evaluate().ImplicitConversionToStringValue().Value + Right.Evaluate().ImplicitConversionToStringValue().Value));
     }
     if (Operator == "&&")
     {
         return(BoolValue.Create(Left.Evaluate().ImplicitConversionToBoolValue().Value&& Right.Evaluate().ImplicitConversionToBoolValue().Value));
     }
     if (Operator == "||")
     {
         return(BoolValue.Create(Left.Evaluate().ImplicitConversionToBoolValue().Value || Right.Evaluate().ImplicitConversionToBoolValue().Value));
     }
     throw new Exception("Internal error: no implementation for operator '" + Operator + "'"); // TODO: different exception type?
 }
Example #23
0
        public async Task DefaultTimeZoneAppliesDaylightSaving()
        {
            // This test ensures that the DST is respected when TZ is rendered

            var input = StringValue.Create("2021-01-01 00:00:00");

            var format  = new FilterArguments(new StringValue("%z"));
            var context = new TemplateContext {
                TimeZone = Pacific
            };

            var result = await MiscFilters.Date(input, format, context);

            Assert.Equal("-0800", result.ToStringValue());

            input = StringValue.Create("2021-06-01 00:00:00");

            result = await MiscFilters.Date(input, format, context);

            Assert.Equal("-0700", result.ToStringValue());
        }
 public BaseValue GetValue(string arrayName, string index)
 {
     this.log.AppendLine($"Array.GetValue(arrayName: '{arrayName}', index: '{index}')");
     return(StringValue.Create(string.Empty));
 }
Example #25
0
 public static IValue Create(string value)
 {
     return(StringValue.Create(value));
 }
 public Task <BaseValue> ReadContents(string filePath)
 {
     this.log.AppendLine($"File.ReadContents(filePath: '{filePath}')");
     return(Task.FromResult(StringValue.Create(string.Empty)));
 }
 public Task <BaseValue> ReadLine(string filePath, decimal lineNumber)
 {
     this.log.AppendLine($"File.ReadLine(filePath: '{filePath}', lineNumber: '{lineNumber}')");
     return(Task.FromResult(StringValue.Create(string.Empty)));
 }
Example #28
0
 public static Account Create(int customerId)
 => new Account(
     customerId,
     StringValue.Create(Guid.NewGuid().ToString()).Value,
     PositiveDecimal.Create(0).Value);
Example #29
0
 public StringValue ImplicitConversionToStringValue()
 {
     return(StringValue.Create(Value ? "true" : "false"));
 }
Example #30
0
 public override Value GetValue(UserItem item)
 {
     return(StringValue.Create(item.Item.Name));
 }