public void Simple_ValueAnnotation_Should_Be_Generated()
        {
            var model = new StubEdmModel();

            var entity = new StubEdmEntityType("NS1", "Person");

            var vt = new StubValueTerm("NS1", "MyValueTerm") { Type = EdmCoreModel.Instance.GetString(true) };
            var va1 = new StubValueAnnotation() { Term = vt, Value = new StubStringConstantExpression("Great!!!") };
            var va2 = new StubValueAnnotation() { Term = vt, Qualifier = "phone", Value = new StubStringConstantExpression("Fabulous!!!") };
            entity.AddVocabularyAnnotation(va1);
            entity.AddVocabularyAnnotation(va2);

            model.Add(entity);

            XElement result = this.generator.GenerateApplicationCsdl(EdmVersion.V40, model);

            string expected = @"
<Schema Namespace='Application.NS1' xmlns='http://docs.oasis-open.org/odata/ns/edm'>
  <Annotations Target='NS1.Person'>
    <Annotation Term='NS1.MyValueTerm' String='Great!!!' />
    <Annotation Term='NS1.MyValueTerm' Qualifier='phone' String='Fabulous!!!' />
  </Annotations>
</Schema>";
            AssertHelper.AssertXElementEquals(expected, result);
        }
        public void Annotations_On_NonEntityType_Should_Be_Generated()
        {
            var model = new StubEdmModel();

            var entity = new StubEdmEntityType("NS1", "Person");
            var vt = new StubValueTerm("NS1", "MyValueTerm") { Type = EdmCoreModel.Instance.GetString(true) };
            var va1 = new StubValueAnnotation() { Term = vt, Value = new StubStringConstantExpression("Great!!!") };
            entity.AddVocabularyAnnotation(va1);
            model.Add(entity);

            var entitySet = new StubEdmEntitySet("personSet", null);
            var va2 = new StubValueAnnotation() { Term = vt, Value = new StubStringConstantExpression("Aha!!!") };
            entitySet.AddVocabularyAnnotation(va2);

            var container = new StubEdmEntityContainer("NS1", "myContainer") { entitySet };
            var va3 = new StubValueAnnotation() { Term = vt, Value = new StubStringConstantExpression("Huh??") };
            container.AddVocabularyAnnotation(va3);
            model.Add(container);

            XElement result = this.generator.GenerateApplicationCsdl(EdmVersion.V40, model);

            string expected = @"
<Schema Namespace='Application.NS1' xmlns='http://docs.oasis-open.org/odata/ns/edm'>
  <Annotations Target='NS1.Person'>
    <Annotation Term='NS1.MyValueTerm' String='Great!!!' />
  </Annotations>
  <Annotations Target='NS1.myContainer'>
    <Annotation Term='NS1.MyValueTerm' String='Huh??' />
  </Annotations>
  <Annotations Target='NS1.myContainer/personSet'>
    <Annotation Term='NS1.MyValueTerm' String='Aha!!!' />
  </Annotations>
</Schema>";
            AssertHelper.AssertXElementEquals(expected, result);
        }
        public void ValueTermDefinitions_InMultipleNamespaces_Should_Be_Generated()
        {
            var model = new StubEdmModel()
            {
                new StubValueTerm("NS1", "fooValueTerm") { Type = EdmCoreModel.Instance.GetInt32(true)},
                new StubValueTerm("NS2", "barValueTerm") { Type = EdmCoreModel.Instance.GetString(false)},
            };

            var fileContents = this.generator.GenerateDefinitionCsdl(EdmVersion.V40, model);
            Assert.AreEqual(2, fileContents.Count());

            var result1 = fileContents.ElementAt(0);
            string expected1 = @"
<Schema Namespace='NS1' xmlns='http://docs.oasis-open.org/odata/ns/edm'>
  <Term Name='fooValueTerm' Type='Edm.Int32' />
</Schema>";
            AssertHelper.AssertXElementEquals(expected1, result1);

            var result2 = fileContents.ElementAt(1);
            string expected2 = @"
<Schema Namespace='NS2' xmlns='http://docs.oasis-open.org/odata/ns/edm'>
  <Term Name='barValueTerm' Type='Edm.String' Nullable='false' />
</Schema>";
            AssertHelper.AssertXElementEquals(expected2, result2);
        }
        public void Initialize()
        {
            this.definitionModel = this.CreateDefinitionModel();

            this.expectedModel = this.CreateApplicationModel();
            this.actualModel = this.CreateApplicationModel();

            this.comparer = new VocabularyModelComparer();
        }
        public static IEdmModel SimpleValueTermInV10()
        {
            StubEdmModel model = new StubEdmModel();

            var titleValueTerm = new StubValueTerm("NS1", "Title") { Type = EdmCoreModel.Instance.GetString(true) };
            model.Add(titleValueTerm);

            return model;
        }
        public static IEdmModel SimpleValueTerms()
        {
            StubEdmModel model = new StubEdmModel();

            var titleValueTerm = new StubValueTerm("NS1", "Title") { Type = EdmCoreModel.Instance.GetString(true) };
            model.Add(titleValueTerm);

            var displaySizeValueTerm = new StubValueTerm("NS2", "DisplaySize") { Type = EdmCoreModel.Instance.GetInt32(false) };
            model.Add(displaySizeValueTerm);

            return model;
        }
        public static IEdmModel SimpleValueTermWithDuplicate()
        {
            StubEdmModel model = new StubEdmModel();

            var titleValueTerm = new StubValueTerm("NS1", "Title") { Type = EdmCoreModel.Instance.GetString(true) };
            model.Add(titleValueTerm);

            var anotherTitleValueTerm = new StubValueTerm("NS1", "Title") { Type = EdmCoreModel.Instance.GetInt32(false) };
            model.Add(anotherTitleValueTerm);

            return model;
        }
        public void Simple_ValueTermDefinitions_Should_Be_Generated()
        {
            var model = new StubEdmModel()
            {
                new StubValueTerm("NS1", "fooValueTerm") { Type = EdmCoreModel.Instance.GetInt32(true) },
                new StubValueTerm("NS1", "barValueTerm") { Type = EdmCoreModel.Instance.GetString(false)},
            };

            XElement result = this.generator.GenerateDefinitionCsdl(EdmVersion.V40, model).Single();

            string expected = @"
<Schema Namespace='NS1' xmlns='http://docs.oasis-open.org/odata/ns/edm'>
  <Term Name='fooValueTerm' Type='Edm.Int32' />
  <Term Name='barValueTerm' Type='Edm.String' Nullable='false' />
</Schema>";
            AssertHelper.AssertXElementEquals(expected, result);
        }
        public static IEdmModel SimpleValueAnnotation()
        {
            StubEdmModel model = new StubEdmModel();
            CreateVocabularyDefinitions(model);

            var person = new StubEdmEntityType("NS1", "Person") 
            { 
                new StubEdmStructuralProperty("Id") { Type = EdmCoreModel.Instance.GetInt16(false) },
                new StubEdmStructuralProperty("FirstName") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("LastName") { Type = EdmCoreModel.Instance.GetString(false) },
            };

            var titleValueTerm = model.FindValueTerm("NS1.Title");
            var titleValueAnnotation = new StubValueAnnotation() { Term = titleValueTerm, Value = new StubStringConstantExpression("Sir") };
            person.AddVocabularyAnnotation(titleValueAnnotation);
            model.Add(person);

            return model;
        }
        public void Simple_ValueTermDefinitions_WithEntityType_InSameNamespace_Should_Be_Generated_Together()
        {
            var model = new StubEdmModel()
            {
                new StubEdmEntityType("NS1", "Person") 
                { 
                    new StubEdmStructuralProperty("Name") { Type = EdmCoreModel.Instance.GetString(isUnbounded:false, maxLength:null, isUnicode:true, isNullable:false)},
                },
                new StubValueTerm("NS1", "fooValueTerm") { Type = EdmCoreModel.Instance.GetInt32(true)},
                new StubValueTerm("NS1", "barValueTerm") { Type = EdmCoreModel.Instance.GetString(false)},
            };

            XElement result = this.generator.GenerateDefinitionCsdl(EdmVersion.V40, model).Single();

            string expected = @"
<Schema Namespace='NS1' xmlns='http://docs.oasis-open.org/odata/ns/edm'>
  <EntityType Name='Person'>
    <Property Name='Name' Type='Edm.String' Nullable='false' />
  </EntityType>
  <Term Name='fooValueTerm' Type='Edm.Int32' />
  <Term Name='barValueTerm' Type='Edm.String' Nullable='false' />
</Schema>";
            AssertHelper.AssertXElementEquals(expected, result);
        }
        public void Simple_ValueTermDefinitions_WithEntityTypes_InDifferentNamespaces_Should_Be_Generated_Separately()
        {
            var model = new StubEdmModel()
            {
                new StubEdmEntityType("NS0", "Person") 
                { 
                    new StubEdmStructuralProperty("Name") { Type = EdmCoreModel.Instance.GetString(isUnbounded:false, maxLength:null, isUnicode:true, isNullable:false) },
                },
                new StubValueTerm("NS1", "fooValueTerm") { Type = EdmCoreModel.Instance.GetInt32(true)},
                new StubValueTerm("NS1", "barValueTerm") { Type = EdmCoreModel.Instance.GetString(false)},
            };

            var fileContents = this.generator.GenerateDefinitionCsdl(EdmVersion.V40, model);
            Assert.AreEqual(2, fileContents.Count());

            var result1 = fileContents.ElementAt(0);
            string expected1 = @"
<Schema Namespace='NS0' xmlns='http://docs.oasis-open.org/odata/ns/edm'>
  <EntityType Name='Person'>
    <Property Name='Name' Type='Edm.String' Nullable='false' />
  </EntityType>
</Schema>";
            AssertHelper.AssertXElementEquals(expected1, result1);

            var result2 = fileContents.ElementAt(1);
            string expected2 = @"
<Schema Namespace='NS1' xmlns='http://docs.oasis-open.org/odata/ns/edm'>
  <Term Name='fooValueTerm' Type='Edm.Int32' />
  <Term Name='barValueTerm' Type='Edm.String' Nullable='false' />
</Schema>";
            AssertHelper.AssertXElementEquals(expected2, result2);
        }
        public static IEdmModel SimpleValueAnnotationOnContainerAndEntitySet()
        {
            StubEdmModel model = new StubEdmModel();
            CreateVocabularyDefinitions(model);

            var person = new StubEdmEntityType("NS1", "Person");
            var container = new StubEdmEntityContainer("NS1", "Container");
            var personSet = new StubEdmEntitySet("PersonSet", container) { Type = new EdmCollectionType(new EdmEntityTypeReference(person, false)) };
            container.Add(personSet);
            model.Add(container);
            model.Add(person);

            var titleValueTerm = model.FindValueTerm("NS1.Title");
            var titleValueAnnotation = new StubValueAnnotation() { Term = titleValueTerm, Value = new StubStringConstantExpression("Sir") };

            container.AddVocabularyAnnotation(titleValueAnnotation);
            personSet.AddVocabularyAnnotation(titleValueAnnotation);

            return model;
        }
        public static IEdmModel StructuredValueAnnotation()
        {
            StubEdmModel model = new StubEdmModel();
            CreateVocabularyDefinitions(model);

            var person = new StubEdmEntityType("NS1", "Person");
            model.Add(person);

            var reviewValueTerm = new StubValueTerm("NS1", "hReviewTerm");
            reviewValueTerm.Type = new StubEdmTypeReference() { Definition = model.FindType("NS1.hReviewEntity"), IsNullable = true };
            model.Add(reviewValueTerm);

            var reviewValueAnnotation = new StubValueAnnotation()
            {
                Term = reviewValueTerm,
                Value = new StubStringConstantExpression("this should be Record"),
            };

            person.AddVocabularyAnnotation(reviewValueAnnotation);

            return model;
        }
        public static IEdmModel ValueTermOfStructuredDataType()
        {
            StubEdmModel model = new StubEdmModel();

            var person = new StubEdmEntityType("NS1", "Person") 
            { 
                new StubEdmStructuralProperty("Id") { Type = EdmCoreModel.Instance.GetInt16(false) },
                new StubEdmStructuralProperty("FirstName") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("LastName") { Type = EdmCoreModel.Instance.GetString(false) },
            };
            model.Add(person);

            var titleValueTerm = new StubValueTerm("NS1", "Title") { Type = person.ToTypeReference(false) };
            model.Add(titleValueTerm);

            return model;
        }
        public static IEdmModel MultipleValueAnnotations()
        {
            StubEdmModel model = new StubEdmModel();
            CreateVocabularyDefinitions(model);

            var person = new StubEdmEntityType("NS1", "Person") 
            { 
                new StubEdmStructuralProperty("Id") { Type = EdmCoreModel.Instance.GetInt16(false) },
                new StubEdmStructuralProperty("FirstName") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("LastName") { Type = EdmCoreModel.Instance.GetString(false) },
            };

            var titleValueTerm = model.FindValueTerm("NS1.Title");
            var titleValueAnnotation = new StubValueAnnotation() { Term = titleValueTerm, Value = new StubStringConstantExpression("Sir") };
            person.AddVocabularyAnnotation(titleValueAnnotation);

            var displaySizeValueTerm = model.FindValueTerm("NS1.DisplaySize");
            var displaySizeValueAnnotation = new StubValueAnnotation() { Term = displaySizeValueTerm, Value = new StubStringConstantExpression("1024") };
            person.AddVocabularyAnnotation(displaySizeValueAnnotation);
            model.Add(person);

            var container = new StubEdmEntityContainer("NS1", "Container");
            var personSet = new StubEdmEntitySet("PersonSet", container) { Type = new EdmCollectionType(new EdmEntityTypeReference(person, false)) };
            personSet.AddVocabularyAnnotation(titleValueAnnotation);
            container.Add(personSet);
            model.Add(container);

            return model;
        }
        public static IEdmModel TypeTermWithInheritance()
        {
            StubEdmModel model = new StubEdmModel();
            var noteTypeTerm = new StubTypeTerm("NS1", "Note")
            {
                new StubEdmStructuralProperty("text") { Type = EdmCoreModel.Instance.GetString(false) },
            };
            model.Add(noteTypeTerm);
            var reviewTypeTerm = new StubTypeTerm("NS1", "Review")
            {
                new StubEdmStructuralProperty("summary") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("itemName") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("dateReviewed") { Type = EdmCoreModel.Instance.GetDateTimeOffset(false) },
                new StubEdmStructuralProperty("rating") { Type = EdmCoreModel.Instance.GetInt32(false) },
            };
            reviewTypeTerm.BaseType = noteTypeTerm;

            model.Add(reviewTypeTerm);

            return model;
        }
        private StubEdmModel CreateDefinitionModel()
        {
            var model = new StubEdmModel();

            var barValueTerm = new StubValueTerm("", "bar") { Type = EdmCoreModel.Instance.GetInt32(true) };
            model.Add(barValueTerm);

            var bazValueTerm = new StubValueTerm("", "baz") { Type = EdmCoreModel.Instance.GetString(true) };
            model.Add(bazValueTerm);

            var p1 = new StubEdmStructuralProperty("p1") { Type = EdmCoreModel.Instance.GetString(true) };
            var p2 = new StubEdmStructuralProperty("p2") { Type = EdmCoreModel.Instance.GetString(true) };
            var foobazTypeTerm = new StubTypeTerm("", "foobaz") { p1, p2 };
            model.Add(foobazTypeTerm);

            var p10 = new StubEdmStructuralProperty("p10") { Type = EdmCoreModel.Instance.GetString(true) };
            var bazfooTypeTerm = new StubTypeTerm("", "bazfoo") { p10 };
            model.Add(bazfooTypeTerm);

            return model;
        }
        public static IEdmModel ValueAnnotationWithRecord()
        {
            StubEdmModel model = new StubEdmModel();
            CreateVocabularyDefinitions(model);

            var person = new StubEdmEntityType("NS1", "Person");
            model.Add(person);

            var reviewValueTerm = new StubValueTerm("NS1", "hReviewTerm");
            reviewValueTerm.Type = new StubEdmTypeReference() { Definition = model.FindType("NS1.hReviewEntity"), IsNullable = true };
            model.Add(reviewValueTerm);

            var recordExpression = new StubRecordExpression();
            recordExpression.AddProperty("Name", new StubStringConstantExpression("Young"));
            recordExpression.AddProperty("IdType", new StubStringConstantExpression("Driver License"));
            var reviewValueAnnotation = new StubValueAnnotation()
            {
                Term = reviewValueTerm,
                Value = recordExpression
            };

            person.AddVocabularyAnnotation(reviewValueAnnotation);

            return model;
        }
        public static IEdmModel TypeTermWithNavigation()
        {
            StubEdmModel model = new StubEdmModel();
            var personTypeTerm = new StubTypeTerm("NS1", "Person")
            {
                new StubEdmStructuralProperty("Name") { Type = EdmCoreModel.Instance.GetString(false) },
            };
            model.Add(personTypeTerm);

            var reviewTypeTerm = new StubTypeTerm("NS1", "Review")
            {
                new StubEdmStructuralProperty("summary") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("itemName") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("dateReviewed") { Type = EdmCoreModel.Instance.GetDateTimeOffset(false) },
                new StubEdmStructuralProperty("rating") { Type = EdmCoreModel.Instance.GetInt32(false) },
            };
            model.Add(reviewTypeTerm);

            var toPerson = new StubEdmNavigationProperty("ToPerson") { Type = new EdmEntityTypeReference(personTypeTerm, false) };
            reviewTypeTerm.Add(toPerson);

            var toReviews = new StubEdmNavigationProperty("ToReviews") {Type = new EdmCollectionType(reviewTypeTerm.ToTypeReference(false)).ToTypeReference(false)};
            personTypeTerm.Add(toReviews);

            toPerson.Partner = toReviews;
            return model;
        }
        private StubEdmModel CreateApplicationModel()
        {
            var model = new StubEdmModel();

            var valueTerm = new StubValueTerm("", "foo") { Type = EdmCoreModel.Instance.GetInt32(true) };
            model.Add(valueTerm);

            var barValueTerm = this.definitionModel.SchemaElements.OfType<IEdmValueTerm>().FirstOrDefault(t => t.Name == "bar");
            var valueAnnotation = new StubValueAnnotation() { Term = barValueTerm, Value = new StubStringConstantExpression("zzz") };
            valueTerm.AddVocabularyAnnotation(valueAnnotation);

            return model;
        }
        private static void CreateVocabularyDefinitions(StubEdmModel model)
        {
            var reviewTypeTerm = new StubTypeTerm("NS1", "hReview")
            {
                new StubEdmStructuralProperty("summary") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("itemName") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("dateReviewed") { Type = EdmCoreModel.Instance.GetDateTimeOffset(false) },
                new StubEdmStructuralProperty("rating") { Type = EdmCoreModel.Instance.GetInt32(false) },
            };
            model.Add(reviewTypeTerm);

            var reviewEntityType = new StubEdmEntityType("NS1", "hReviewEntity")
            {
                new StubEdmStructuralProperty("summary") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("itemName") { Type = EdmCoreModel.Instance.GetString(false) },
                new StubEdmStructuralProperty("dateReviewed") { Type = EdmCoreModel.Instance.GetDateTimeOffset(false) },
                new StubEdmStructuralProperty("rating") { Type = EdmCoreModel.Instance.GetInt32(false) },
            };
            model.Add(reviewEntityType);

            var titleValueTerm = new StubValueTerm("NS1", "Title") { Type = EdmCoreModel.Instance.GetString(true) };
            model.Add(titleValueTerm);

            var displaySizeValueTerm = new StubValueTerm("NS1", "DisplaySize") { Type = EdmCoreModel.Instance.GetInt32(false) };
            model.Add(displaySizeValueTerm);
        }
        public void ValidateKindsOfNone()
        {
            StubEdmModel model = new StubEdmModel();
            EdmEntityContainer container = new EdmEntityContainer("namespace", "container");
            model.Add(container);

            model.Add(new NoneKinds1("namespace", "badThing", container));
            var type = new EdmEntityType("namespace", "type");
            type.AddProperty(new NoneKinds2("namespace", "otherBadThing", EdmCoreModel.Instance.GetInt32(false), type));
            model.Add(type);

            var expectedErrors = new EdmLibTestErrors()
            {
                { "(EdmLibTests.FunctionalTests.CodeCoverageBoostingTests+NoneKinds1)", EdmErrorCode.TypeMustNotHaveKindOfNone },
                { "(EdmLibTests.FunctionalTests.CodeCoverageBoostingTests+NoneKinds1)", EdmErrorCode.TermMustNotHaveKindOfNone },
                { "(EdmLibTests.FunctionalTests.CodeCoverageBoostingTests+NoneKinds1)", EdmErrorCode.EntityContainerElementMustNotHaveKindOfNone },
                { "(EdmLibTests.FunctionalTests.CodeCoverageBoostingTests+NoneKinds1)", EdmErrorCode.SchemaElementMustNotHaveKindOfNone },
                { "(namespace.type)", EdmErrorCode.KeyMissingOnEntityType },
                { "(EdmLibTests.FunctionalTests.CodeCoverageBoostingTests+NoneKinds2)", EdmErrorCode.PrimitiveTypeMustNotHaveKindOfNone },
                { "(EdmLibTests.FunctionalTests.CodeCoverageBoostingTests+NoneKinds2)", EdmErrorCode.SchemaElementMustNotHaveKindOfNone },
                { "(EdmLibTests.FunctionalTests.CodeCoverageBoostingTests+NoneKinds2)", EdmErrorCode.TypeMustNotHaveKindOfNone },
                { "(EdmLibTests.FunctionalTests.CodeCoverageBoostingTests+NoneKinds2)", EdmErrorCode.PropertyMustNotHaveKindOfNone },
            };
            this.VerifySemanticValidation(model, expectedErrors);

        }
        public static IEdmModel SimpleValueAnnotationConfict()
        {
            StubEdmModel model = new StubEdmModel();
            CreateVocabularyDefinitions(model);

            var person = new StubEdmEntityType("NS1", "Person");

            var titleValueTerm = model.FindValueTerm("NS1.Title");
            var titleValueAnnotation = new StubValueAnnotation() { Term = titleValueTerm, Value = new StubStringConstantExpression("Sir") };
            person.AddVocabularyAnnotation(titleValueAnnotation);
            var titleValueAnnotation2 = new StubValueAnnotation() { Term = titleValueTerm, Value = new StubStringConstantExpression("Senor") };
            person.AddVocabularyAnnotation(titleValueAnnotation2);

            model.Add(person);

            return model;
        }