public void ReplaceReference()
        {
            EqualSpecification equal = new EqualSpecification(
                "k1",
                SpecificationValue.Ref("{p1}"));

            ValueReferenceVisitor visitor = new ValueReferenceVisitor(
                new Dictionary <string, object>
            {
                { "{p1}", SpecificationValue.Ref("{p2}") },
                { "{p2}", SpecificationValue.Single("qwe") },
            });

            Specification result = visitor.Visit(equal);

            var r = Assert.IsType <EqualSpecification>(result);

            Assert.NotSame(equal, r);
            Assert.Contains("qwe", r.Value.Values);
            Assert.DoesNotContain("{p1}", r.Value.Values);
            Assert.DoesNotContain("{p2}", r.Value.Values);
            Assert.Equal(equal.Key, r.Key);
            Assert.Equal(SpecificationValueSettings.DefaultAllOf.DefaultMultiplicity, r.Value.ValueMultiplicity);
            Assert.Equal(SpecificationValue.DataType.String, r.Value.ValueType);
        }
        public static T ResolveValueRefs <T>(
            this T specification,
            IReadOnlyDictionary <string, object> values,
            ReferenceResolutionSettings settings = null)
            where T : Specification
        {
            ValueReferenceVisitor visitor = new ValueReferenceVisitor(values, settings);

            return((T)visitor.Visit(specification));
        }
        public void ReplaceCircular()
        {
            EqualSpecification equal = new EqualSpecification(
                "k1",
                SpecificationValue.Ref("{p1}"));

            ValueReferenceVisitor visitor = new ValueReferenceVisitor(
                new Dictionary <string, object>
            {
                { "{p1}", SpecificationValue.Ref("{p2}") },
                { "{p2}", SpecificationValue.Ref("{p1}") },
            });

            var exc = Assert.Throws <InvalidOperationException>(() => visitor.Visit(equal));

            Assert.Contains("Circular references detected", exc.Message);
        }
        public void ReplaceInt()
        {
            EqualSpecification equal = new EqualSpecification(
                "k1",
                SpecificationValue.Ref("{p1}"));

            ValueReferenceVisitor visitor =
                new ValueReferenceVisitor(new Dictionary <string, object> {
                { "{p1}", 2 }
            });

            Specification result = visitor.Visit(equal);

            var r = Assert.IsType <EqualSpecification>(result);

            Assert.NotSame(equal, r);
            Assert.Contains(2, r.Value.Values);
            Assert.DoesNotContain("{p1}", r.Value.Values);
            Assert.Equal(SpecificationValue.DataType.Int, r.Value.ValueType);
        }
        public void ReplaceStringArray()
        {
            EqualSpecification equal = new EqualSpecification(
                "k1",
                SpecificationValue.Ref("{p1}"));

            ValueReferenceVisitor visitor =
                new ValueReferenceVisitor(new Dictionary <string, object> {
                { "{p1}", new[] { "v1", "v2" } }
            });

            Specification result = visitor.Visit(equal);

            var r = Assert.IsType <EqualSpecification>(result);

            Assert.NotSame(equal, r);
            Assert.Contains("v1", r.Value.Values);
            Assert.DoesNotContain("{p1}", r.Value.Values);
            Assert.Equal(equal.Key, r.Key);
            Assert.Equal(equal.Value.ValueMultiplicity, r.Value.ValueMultiplicity);
            Assert.Equal(equal.Value.ValueType, r.Value.ValueType);
        }
        public void ReplaceNoKeysIgnore()
        {
            EqualSpecification equal = new EqualSpecification(
                "k1",
                SpecificationValue.Ref("{p1}"));

            ValueReferenceVisitor visitor = new ValueReferenceVisitor(
                new Dictionary <string, object> {
                { "{p2}", "v1" }
            },
                new ReferenceResolutionSettings {
                ThrowValueErrors = false
            });

            Specification result = visitor.Visit(equal);

            var r = Assert.IsType <EqualSpecification>(result);

            Assert.Same(equal, r);
            Assert.Contains("{p1}", r.Value.Values);
            Assert.DoesNotContain("v1", r.Value.Values);
        }
        public void ReplaceReferenceIncorrectType()
        {
            EqualSpecification equal = new EqualSpecification(
                "k1",
                SpecificationValue.Ref("{p1}"));

            ValueReferenceVisitor visitor = new ValueReferenceVisitor(
                new Dictionary <string, object>
            {
                { "{p1}", SpecificationValue.Ref("{p2}") },
                { "{p2}", TimeSpan.FromDays(1) },
            });

            InvalidOperationException exc = Assert.Throws <InvalidOperationException>(() => visitor.Visit(equal));

            Assert.Contains("Unable to resolve", exc.Message);
            Assert.Contains("{p1}", exc.ToString());
            Assert.Contains("{p2}", exc.ToString());
        }
        public void ReplaceInconsistentTypes()
        {
            EqualSpecification equal = new EqualSpecification(
                "k1",
                SpecificationValue.Ref("{p1}"));

            ValueReferenceVisitor visitor =
                new ValueReferenceVisitor(new Dictionary <string, object> {
                { "{p1}", TimeSpan.FromDays(1) }
            });

            InvalidOperationException exc = Assert.Throws <InvalidOperationException>(() => visitor.Visit(equal));

            Assert.Contains("Unable to resolve value reference for k1 equal ref({p1}). Value of type System.TimeSpan not supported.", exc.Message);
        }
        public void ReplaceNoKeysThrowDefault()
        {
            EqualSpecification equal = new EqualSpecification(
                "k1",
                SpecificationValue.Ref("{p1}"));

            ValueReferenceVisitor visitor =
                new ValueReferenceVisitor(new Dictionary <string, object> {
                { "{p2}", "v1" }
            });

            InvalidOperationException exc = Assert.Throws <InvalidOperationException>(() => visitor.Visit(equal));

            Assert.Contains("Unable to resolve value reference for k1 equal ref({p1}). Key {p1} is missing", exc.Message);
        }