public void WhenIsClassProperty_CSharpCodeGen_GeneratesGetSetValueWithNoRef()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""false"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                            },
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            Assert.IsTrue(code.ToString().Contains("GetValue(this"));
            Assert.IsTrue(code.ToString().Contains("SetValue(this"));
        }
        public void WhenPropertyIsInherited_CSharpCodeGen_DoestNotGeneratesBackingField()

        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsAbstractClass"": ""true"",
                        ""IsValueType"": ""true"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                                ""InheritedPropertyFrom"": ""BaseClass"",
                            },
                        }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            // TODO tokenize, bad britle test, should use proper test for backing field existance
            Assert.IsFalse(code.ToString().Contains("int m_Data;"));
            Assert.IsTrue(code.ToString().Contains("new InheritedProperty<BaseClass, HelloWorld, int>(s_DataProperty)"));
        }
        public void WhenOverrideDefaultBaseClasseClass_CSharpCodeGen_GeneratesContainerWithOverridenBaseClass()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""OverrideDefaultBaseClass"": ""Foo"",
                        ""Properties"": { }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            // TODO tokenize, bad britle test
            Assert.IsTrue(code.ToString().Contains("public partial class HelloWorld : Foo"));
        }
        public void WhenPropertyContainerSetAsAbstractForStructContainer_CSharpCodeGen_DoestNotGeneratesAbstractStruct()

        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsAbstractClass"": ""true"",
                        ""IsValueType"": ""true"",
                        ""Properties"": {
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            // TODO tokenize, bad britle test
            Assert.IsTrue(code.ToString().Contains("public partial struct HelloWorld : IPropertyContainer"));
        }
        public void WhenIsClassContainerAndNoProperties_CSharpCodeGen_DoesNotGenerateConstructor()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""false"",
                        ""Properties"": {
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            // TODO tokenize
            Assert.IsFalse(code.ToString().Contains("public HelloWorld ()"));
        }
        public void WhenPropertyDeclaredAsReadonly_CSharpCodeGen_GeneratesReadonlyPropertyAccessor()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""true"",
                        ""GeneratedUserHooks"": ""OnPropertyConstructed"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                                ""IsReadonlyProperty"": ""true"",
                            },
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            // TODO tokenize, very BAD
            Assert.IsTrue(code.ToString().Contains("/* GET */"));
            Assert.IsTrue(code.ToString().Contains("/* SET */ null"));
        }
        public void WhenIsStructProperty_CSharpCodeGen_NoDefaultValue()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""true"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                            },
                            ""Ints"": {
                                ""TypeId"": ""List"",
                                ""ItemTypeId"": ""float"",
                            },
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            // TODO tokenize
            Assert.IsTrue(code.ToString().Contains("private int m_Data;"));
            Assert.IsTrue(code.ToString().Contains("private readonly List<float> m_Ints= new List<float> {};"));
        }
        public void WhenValueTypeNotSpecified_CSharpCodeGen_GeneratesAStructContainer()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""true"",
                        ""Properties"": { }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            Assert.IsTrue(code.ToString().Contains("public partial struct HelloWorld"));
        }
        public void WhenIsClassContainerContainsStructProperty_CSharpCodeGen_GeneratesProperyContainerWrapper()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""false"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""Foo"",
                                ""IsValueType"": ""true"",
                            },
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            Assert.IsTrue(code.ToString().Contains("ContainerProperty<HelloWorld, Foo>"));
        }
        public void WhenBackingFieldGenerated_CSharpCodeGen_TheyAreGeneratedAsPrivate()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""Foo"",
                                ""IsValueType"": ""true"",
                            },
                            ""Foo"": {
                                ""TypeId"": ""int""
                            },
                        }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            Assert.IsTrue(code.ToString().Contains("private int m_Foo;"));
            Assert.IsTrue(code.ToString().Contains("private readonly Foo m_Data;"));
        }
        public void WhenBasicTypesInSchema_SchemaReadser_ReturnsAValidContainerList()
        {
            var result = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""SchemaVersion"": 1,
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""TypeId"": ""1"",
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""false"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                                ""DefaultValue"": ""5""
                            },
                            ""Floats"": {
                                ""TypeId"": ""List"",
                                ""ItemTypeId"": ""float""
                            },
                            ""Ints"": {
                                ""TypeId"": ""Array"",
                                ""ItemTypeId"": ""int""
                            },
                            ""Struct"": {
                                ""TypeId"": ""SomeData""
                            }
                        }
                        }
                     ]
                 }
            ]
        ");

            Assert.AreEqual(1, result.Count);
            Assert.AreEqual("HelloWorld", result[0].TypeName);
            Assert.IsTrue(result[0].Tag == PropertyTypeNode.TypeTag.Class);
            Assert.AreEqual(4, result[0].Children.Count);
            Assert.AreEqual(new System.Collections.Generic.List <string> {
                "Data", "Floats", "Ints", "Struct"
            },
                            result[0].Children.Select(c => c.Name)
                            );
            Assert.AreEqual(new System.Collections.Generic.List <string> {
                "int", "List", "Array", "SomeData"
            },
                            result[0].Children.Select(c => c.TypeName)
                            );
            Assert.AreEqual(new System.Collections.Generic.List <string> {
                "5", "", "", ""
            },
                            result[0].Children.Select(c => c.DefaultValue)
                            );
            Assert.AreEqual(new System.Collections.Generic.List <string> {
                "", "float", "int", ""
            },
                            result[0].Children.Select(c => (c.Of != null ? c.Of.TypeName : string.Empty))
                            );
        }
        public void WhenEmptyStringForSchema_CSharpCodeGen_ReturnsAnEmptyContainerList()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(string.Empty);

            backend.Generate(result);
            var code = backend.Code;

            Assert.Zero(code.Length);
        }
        public void WhenNoTypesInSchema_SchemaReadser_ReturnsAnEmptyContainerList()
        {
            var result = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""SchemaVersion"": 1,
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": []
                 }
            ]
        ");

            Assert.Zero(result.Count);
        }
        public void WhenNoTypesInSchema_CSharpCodeGen_ReturnsAnEmptyContainerList()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""SchemaVersion"": 1,
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": []
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.Zero(code.Length);
        }
        public void WhenClassContainerWithBaseTypes_CSharpCodeGen_ReturnsAValidContainerList()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""SchemaVersion"": 1,
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""TypeId"": ""1"",
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""false"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                                ""DefaultValue"": ""5""
                            },
                            ""Floats"": {
                                ""TypeId"": ""List"",
                                ""ItemTypeId"": ""float""
                            },
                            ""Struct"": {
                                ""TypeId"": ""SomeData"",
                                ""IsValueType"": ""true""
                            }
                        }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            Assert.IsTrue(code.ToString().Contains("Property<HelloWorld, int>"));
            Assert.IsTrue(code.ToString().Contains("ListProperty<HelloWorld, List<float>, float>"));
            Assert.IsTrue(code.ToString().Contains("MutableContainerProperty<HelloWorld, SomeData>"));
        }
        public void WhenTypeWithBackingFieldInSchema_CSharpCodeGen_DoesNotGeneratePrivateDataMembers()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""SchemaVersion"": 1,
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""TypeId"": ""1"",
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""false"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                                ""DefaultValue"": ""5"",
                                ""BackingField"": ""backing""
                            },
                            ""Floats"": {
                                ""TypeId"": ""List"",
                                ""ItemTypeId"": ""float"",
                                ""BackingField"": ""backing""
                            },
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            Assert.IsFalse(code.ToString().Contains("m_Data"));
            Assert.IsFalse(code.ToString().Contains("m_Floats"));
            Assert.IsTrue(code.ToString().Contains(".backing"));
            Assert.IsTrue(code.ToString().Contains(".backing"));
        }
        public void WhenClassType_SchemaReadser_ReturnsTypeTagAsStruct()
        {
            var result = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""SchemaVersion"": 1,
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""TypeId"": ""1"",
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""true"",
                        ""Properties"": { }
                      }
                    ]
                 }
            ]
        ");

            Assert.AreEqual(1, result.Count);
            Assert.AreEqual("HelloWorld", result[0].TypeName);
            Assert.IsTrue(result[0].Tag == PropertyTypeNode.TypeTag.Struct);
        }
        public void WhenUserHookSpecified_CSharpCodeGen_GeneratesIt()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""true"",
                        ""GeneratedUserHooks"": ""OnPropertyConstructed"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                            },
                            ""Ints"": {
                                ""TypeId"": ""List"",
                                ""ItemTypeId"": ""float"",
                            },
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            // TODO tokenize
            Assert.IsTrue(code.ToString().Contains("partial static void OnPropertyBagConstructed(IPropertyBag bag);"));
            Assert.IsTrue(code.ToString().Contains("OnPropertyBagConstructed(sProperties);"));
        }
        public void WhenIsClassProperty_CSharpCodeGen_DelegatesDefaultValueBackingFieldConstruction()
        {
            var backend = new CSharpGenerationBackend();
            var result  = JsonPropertyContainerSchemaReader.Read(@"
            [
                {
                    ""Namespace"": ""Unity.Properties.Samples.Schema"",
                    ""Types"": [
                      {
                        ""Name"": ""HelloWorld"",
                        ""IsValueType"": ""false"",
                        ""Properties"": {
                            ""Data"": {
                                ""TypeId"": ""int"",
                                ""DefaultValue"": ""5"",
                            },
                            ""Ints"": {
                                ""TypeId"": ""List"",
                                ""ItemTypeId"": ""float"",
                            },
                          }
                        }
                     ]
                 }
            ]
        ");

            backend.Generate(result);
            var code = backend.Code;

            Assert.NotZero(code.Length);
            Debug.Log(code);
            Assert.IsTrue(code.ToString().Contains("int m_Data;"));
            Assert.IsTrue(code.ToString().Contains("m_Data = 5;"));
            Assert.IsTrue(code.ToString().Contains("m_Ints = new List<float> {};"));
        }
        public void WhenEmptyStringForSchema_SchemaReader_ReturnsAnEmptyContainerList()
        {
            var result = JsonPropertyContainerSchemaReader.Read(string.Empty);

            Assert.Zero(result.Count);
        }