public void DecorateClassRenamingTest()
        {
            var dec = new SubresourceClassDecorator();
            var resource = new MockResource();
            const string className = "TestClass";
            var decl = new CodeTypeDeclaration();
            const string serviceName = "TestService";
            var decorators = new IResourceDecorator[0];

            // Create generators.
            var resourceGen = new ResourceContainerGenerator(new IResourceContainerDecorator[0]);
            var requestGen = new RequestClassGenerator(new IRequestDecorator[0]);
            var gen = new ResourceClassGenerator(
                resource, serviceName, decorators, requestGen, resourceGen, new string[0]);

            // Add subresources.
            resource.Resources.Add("Sub1", new MockResource { Name = "Sub1" });
            resource.Resources.Add("Sub2", new MockResource { Name = "Sub2" });

            // Add existing members
            decl.Members.Add(new CodeMemberField { Name = "Sub1Resource" });

            // Test decoration.
            dec.DecorateClass(resource, className, decl, gen, serviceName, decorators);
            Assert.AreEqual(3, decl.Members.Count);
            Assert.AreEqual("Sub1Resource", decl.Members[0].Name);
            Assert.AreEqual("Sub1Res", decl.Members[1].Name);
            Assert.AreEqual("Sub2Resource", decl.Members[2].Name);
        }
        public void DecorateClassTest()
        {
            var method = new MockMethod() { Name = "Method", Parameters = new Dictionary<string, IParameter>() };
            method.Parameters.Add("Param", new MockParameter() { Name = "Param" });
            var resource = new MockResource();
            resource.Methods.Add("Method", method);
            var resourceDecl = new CodeTypeDeclaration();
            var requestDecl = new CodeTypeDeclaration();
            var typeProvider = new DefaultObjectTypeProvider("Schema");

            // Confirm that the decorator has run correctly.
            var decorator = new RequestConstructorDecorator(typeProvider) { CreateOptionalConstructor = true };
            decorator.DecorateClass(resource, method, requestDecl, resourceDecl);
            Assert.AreEqual(2, requestDecl.Members.Count); // 2 Constructors.
            Assert.IsInstanceOf<CodeConstructor>(requestDecl.Members[0]);
            Assert.AreEqual(0, resourceDecl.Members.Count);

            // Test the decorator without optional parameters.
            requestDecl = new CodeTypeDeclaration();
            decorator.CreateOptionalConstructor = false;
            decorator.DecorateClass(resource, method, requestDecl, resourceDecl);
            Assert.AreEqual(1, requestDecl.Members.Count); // 1 Constructor.
            Assert.IsInstanceOf<CodeConstructor>(requestDecl.Members[0]);
            Assert.AreEqual(0, resourceDecl.Members.Count);
        }
        public void GenerateParameterPropertyTest()
        {
            var parameter = new MockParameter() { Name = "Param" };
            var method = new MockMethod() { Name = "Method", Parameters = new Dictionary<string, IParameter>() };
            method.Parameters.Add("Param", parameter);
            var resource = new MockResource();
            resource.Methods.Add("Method", method);
            var resourceDecl = new CodeTypeDeclaration();

            // Confirm that two properties and two fields are generated.
            var decorator = new ParameterPropertyDecorator();
            CodeTypeMemberCollection newMembers = decorator.GenerateParameterProperty(
                parameter, method, resourceDecl, Enumerable.Empty<string>());
            Assert.AreEqual(2, newMembers.Count); // Property  + field.
            Assert.AreEqual(0, resourceDecl.Members.Count);

            // Check the generated property.
            Assert.IsInstanceOf<CodeMemberField>(newMembers[0]);

            CodeMemberProperty property = (CodeMemberProperty)newMembers[1];
            Assert.AreEqual("Param", property.Name);

            // Check that the property has a Key attribute.
            Assert.AreEqual(1, property.CustomAttributes.Count);
            Assert.AreEqual(
                typeof(RequestParameterAttribute).FullName, property.CustomAttributes[0].AttributeType.BaseType);
            Assert.AreEqual(
                "Param", ((CodePrimitiveExpression) property.CustomAttributes[0].Arguments[0].Value).Value);
        }
        public void DecorateClassTest()
        {
            var dec = new SubresourceClassDecorator();
            var resource = new MockResource();
            const string className = "TestClass";
            var decl = new CodeTypeDeclaration();
            const string serviceName = "TestService";
            var decorators = new IResourceDecorator[0];

            // Create generators.
            var resourceGen = new ResourceContainerGenerator(new IResourceContainerDecorator[0]);
            var requestGen = new RequestClassGenerator(new IRequestDecorator[0]);
            var gen = new ResourceClassGenerator(
                resource, serviceName, decorators, requestGen, resourceGen, new string[0]);

            // Add subresources.
            resource.Resources.Add("Sub1", new MockResource { Name = "Sub1" });
            resource.Resources.Add("Sub2", new MockResource { Name = "Sub2" });

            // Test decoration.
            dec.DecorateClass(resource, className, decl, gen, serviceName, decorators);
            Assert.AreEqual(2, decl.Members.Count);
            Assert.IsInstanceOf<CodeTypeDeclaration>(decl.Members[0]);
            Assert.IsInstanceOf<CodeTypeDeclaration>(decl.Members[1]);
        }
        public void AddRequiredParametersTest()
        {
            var parameterA = new MockParameter() { Name = "ParamA", IsRequired = false };
            var parameterB = new MockParameter() { Name = "ParamB", IsRequired = true};
            var method = new MockMethod() { Name = "Method", Parameters = new Dictionary<string, IParameter>() };
            method.Parameters.Add("ParamA", parameterA);
            method.Parameters.Add("ParamB", parameterB);
            var resource = new MockResource();
            resource.Methods.Add("Method", method);
            var resourceDecl = new CodeTypeDeclaration();
            var typeProvider = new DefaultObjectTypeProvider("Schema");

            // Confirm that the "service" parameter is added.
            var decorator = new RequestConstructorDecorator(typeProvider);
            CodeConstructor constructor = new CodeConstructor();
            decorator.AddRequestParameters(resourceDecl, method, constructor, false);

            Assert.AreEqual(1, constructor.Parameters.Count);
            Assert.AreEqual("paramB", constructor.Parameters[0].Name);
            Assert.AreEqual(1, constructor.Statements.Count);

            // Check that optional parameters are added when the appropriate flag is set.
            constructor = new CodeConstructor();
            decorator.AddRequestParameters(resourceDecl, method, constructor, true);

            Assert.AreEqual(2, constructor.Parameters.Count);
            Assert.AreEqual("paramB", constructor.Parameters[0].Name);
            Assert.AreEqual("paramA", constructor.Parameters[1].Name);
            Assert.AreEqual(2, constructor.Statements.Count);
        }
        public void GenerateRequestClassesTest()
        {
            var decorator = new CountingRequestDecorator();
            var generator = new RequestClassGenerator(new IRequestDecorator[] { decorator });
            var decl = new CodeTypeDeclaration();

            // Create a test resource.
            var resource = new MockResource();
            resource.Methods.Add("MethodA", new MockMethod() { Name = "MethodA"});
            resource.Methods.Add("MethodB", new MockMethod() { Name = "MethodB"});

            // Run the generator
            CodeTypeMemberCollection collection = generator.GenerateRequestClasses(decl, resource);
            Assert.AreEqual(2, decorator.TimesCalled);
            Assert.AreEqual(2, collection.Count);
            Assert.IsInstanceOf<CodeTypeDeclaration>(collection[0]);
            Assert.IsInstanceOf<CodeTypeDeclaration>(collection[1]);
            CollectionAssert.AreEqual(
                new[]
                    {
                        string.Format(RequestClassGenerator.RequestClassNamingScheme, "MethodA"),
                        string.Format(RequestClassGenerator.RequestClassNamingScheme, "MethodB"),
                    },
                from CodeTypeMember m in collection select m.Name);
        } 
        public void DecorateClassNonBodyTest()
        {
            var decorator = new BodyPropertyDecorator(new DefaultObjectTypeProvider("Schema"));
            var resource = new MockResource();
            var method = new MockMethod() { Name = "Test", HasBody = false };
            var decl = new CodeTypeDeclaration();
            var resourceDecl = new CodeTypeDeclaration();
            decorator.DecorateClass(resource, method, decl, resourceDecl);

            Assert.AreEqual(0, decl.Members.Count);
        }
        public void DecorateClassTest()
        {
            var decorator = new ServiceRequestInheritanceDecorator(new DefaultObjectTypeProvider("Schema"));
            var resource = new MockResource();
            var method = new MockMethod() { ResponseType = "MySchema" };
            var decl = new CodeTypeDeclaration();
            var resourceDecl = new CodeTypeDeclaration();

            // Check for ": ServiceRequest<Schema.MySchema>".
            decorator.DecorateClass(resource, method, decl, resourceDecl);
            Assert.AreEqual(1, decl.BaseTypes.Count);
            Assert.AreEqual(typeof(ServiceRequest<>).FullName, decl.BaseTypes[0].BaseType);
            Assert.AreEqual(1, decl.BaseTypes[0].TypeArguments.Count);
            Assert.AreEqual("Schema.MySchema", decl.BaseTypes[0].TypeArguments[0].BaseType);
        }
        public void DecorateClassTest()
        {
            var method = new MockMethod() { Name = "Method", Parameters = new Dictionary<string, IParameter>()};
            method.Parameters.Add("Param", new MockParameter() { Name = "Param"});
            method.Parameters.Add("Param2", new MockParameter() { Name = "Param2"});
            var resource = new MockResource();
            resource.Methods.Add("Method", method);
            var resourceDecl = new CodeTypeDeclaration();
            var requestDecl = new CodeTypeDeclaration();

            // Confirm that the decorator adds the two parameters as properties with a backing field each.
            var decorator = new ParameterPropertyDecorator();
            decorator.DecorateClass(resource, method, requestDecl, resourceDecl);
            Assert.AreEqual(4, requestDecl.Members.Count); // 2 properties + 2 field.
            Assert.AreEqual(0, resourceDecl.Members.Count);
        }
        public void DecorateClassTest()
        {
            var decorator = new BodyPropertyDecorator(new DefaultObjectTypeProvider("Schema"));
            var resource = new MockResource();
            var method = new MockMethod() { Name = "Test", RequestType = "SomeSchema", HasBody = true };
            var decl = new CodeTypeDeclaration();
            var resourceDecl = new CodeTypeDeclaration();
            decorator.DecorateClass(resource, method, decl, resourceDecl);

            Assert.AreEqual(3, decl.Members.Count);
            Assert.IsInstanceOf<CodeMemberField>(decl.Members[0]);
            Assert.IsInstanceOf<CodeMemberProperty>(decl.Members[1]);
            Assert.AreEqual("Body", decl.Members[1].Name);
            Assert.IsInstanceOf<CodeMemberMethod>(decl.Members[2]);
            Assert.AreEqual("GetBody", decl.Members[2].Name);
        }
        public void GenerationTest()
        {
            var resource = new MockResource();
            resource.Name = "Test";
            resource.Methods.Add(
                "TestMethod", new MockMethod { Name = "TestMethod", HttpMethod = "GET", ResponseType = "int" });

            // Run the generator.
            var counter = new CountingDecorator();
            var generator = ConstructGenerator(resource, counter, new SubresourceClassDecorator());
            CodeTypeDeclaration clss = generator.CreateClass();
            Assert.IsNotNull(clss);
            Assert.AreEqual("TestResource", clss.Name);

            // Confirm that decorators have run.
            Assert.AreEqual(1, counter.Count);
        }
        public void CreateConstructorTest()
        {
            var parameter = new MockParameter() { Name = "Param", IsRequired = true };
            var method = new MockMethod() { Name = "Method", Parameters = new Dictionary<string, IParameter>() };
            method.Parameters.Add("Param", parameter);
            var resource = new MockResource();
            resource.Methods.Add("Method", method);
            var resourceDecl = new CodeTypeDeclaration();
            var typeProvider = new DefaultObjectTypeProvider("Schema");

            // Confirm that the "service" parameter is added.
            var decorator = new RequestConstructorDecorator(typeProvider);
            CodeConstructor constructor = decorator.CreateRequiredConstructor(resourceDecl, method, false);
            Assert.AreEqual(2, constructor.Parameters.Count);
            Assert.AreEqual("service", constructor.Parameters[0].Name);
            Assert.AreEqual(1, constructor.BaseConstructorArgs.Count);
        }
        public void DecorateClassTest()
        {
            var method = new MockMethod() { Name = "Method", Parameters = new Dictionary<string, IParameter>() };
            method.Parameters.Add("Param", new MockParameter() { Name = "Param" });
            var resource = new MockResource();
            resource.Methods.Add("Method", method);
            var resourceDecl = new CodeTypeDeclaration();
            var requestDecl = new CodeTypeDeclaration();

            // Confirm that the decorator has run correctly.
            var decorator = new ServiceRequestFieldDecorator();
            decorator.DecorateClass(resource, method, requestDecl, resourceDecl);
            Assert.AreEqual(2, requestDecl.Members.Count); // 2 properties
            Assert.IsInstanceOf<CodeMemberProperty>(requestDecl.Members[0]);
            Assert.IsInstanceOf<CodeMemberProperty>(requestDecl.Members[1]);
            Assert.AreEqual("ResourcePath", requestDecl.Members[0].Name);
            Assert.AreEqual("MethodName", requestDecl.Members[1].Name);
        }
        public void SubresourceGenerationTest()
        {
            var subresource = new MockResource();
            subresource.Name = "Sub";

            var resource = new MockResource();
            resource.Name = "Test";
            resource.Resources .Add(new KeyValuePair<string, IResource>("Sub", subresource));

            // Run the generator.
            var counter = new CountingDecorator();
            var generator = ConstructGenerator(resource, counter, new SubresourceClassDecorator());
            CodeTypeDeclaration clss = generator.CreateClass();
            Assert.IsNotNull(clss);
            Assert.AreEqual(2, counter.Count);

            // Confirm that a subclass has been added.
            var subtypes = from CodeTypeMember m in clss.Members where (m is CodeTypeDeclaration) select m;
            Assert.AreEqual(1, subtypes.Count());
            Assert.AreEqual("SubResource", subtypes.First().Name);
        }
        public void CreateMethodTest()
        {
            const string className = "TestClass";
            var typeProvider = new DefaultObjectTypeProvider("Schema");
            var commentCreator = new DefaultEnglishCommentCreator();
            var generator = new RequestMethodResourceDecorator.ResourceGenerator(
                className, typeProvider, commentCreator);

            // Generate a method.
            var decl = new CodeTypeDeclaration();
            var resource = new MockResource();
            var method = new MockMethod() { Name = "Test", Parameters = new Dictionary<string, IParameter>()};
            method.Parameters.Add(
                "a", new MockParameter() { Name = "a", ParameterType = "string", IsRequired = false });
            method.Parameters.Add(
                "b", new MockParameter() { Name = "b", ParameterType = "string", IsRequired = true });
            CodeMemberMethod generatedMethod = generator.CreateMethod(decl, resource, method, true);

            Assert.AreEqual("Test", generatedMethod.Name);
            Assert.AreEqual(2, generatedMethod.Parameters.Count); // two parameters defined.
            Assert.AreEqual(1, generatedMethod.Statements.Count); // one "new ...Request()" statement.
            Assert.AreEqual("TestRequest", generatedMethod.ReturnType.BaseType);
        }
        public void DecorateClassValidationTest()
        {
            var dec = new SubresourceClassDecorator();
            var resource = new MockResource();
            const string className = "TestClass";
            var decl = new CodeTypeDeclaration();
            const string serviceName = "TestService";
            IEnumerable<IResourceDecorator> decorators =
                GoogleServiceGenerator.GetSchemaAwareResourceDecorators("Generated.Data.");

            // Create generators.
            var resourceGen = new ResourceContainerGenerator(
                GoogleServiceGenerator.StandardResourceContainerDecorator);
            var requestGen = new RequestClassGenerator(new IRequestDecorator[0]);
            var gen = new ResourceClassGenerator(
                resource, serviceName, decorators, requestGen, resourceGen, new string[0]);

            // Validate method:
            Assert.Throws<ArgumentNullException>(
                () => dec.DecorateClass(null, className, decl, gen, serviceName, decorators));
            Assert.Throws<ArgumentNullException>(
                () => dec.DecorateClass(resource, null, decl, gen, serviceName, decorators));
            Assert.Throws<ArgumentNullException>(
                () => dec.DecorateClass(resource, className, null, gen, serviceName, decorators));
            Assert.Throws<ArgumentNullException>(
                () => dec.DecorateClass(resource, className, decl, null, serviceName, decorators));
            Assert.Throws<ArgumentNullException>(
                () => dec.DecorateClass(resource, className, decl, gen, null, decorators));
            Assert.Throws<ArgumentNullException>(
                () => dec.DecorateClass(resource, className, decl, gen, serviceName, null));

            // Test normal use case.
            dec.DecorateClass(resource, className, decl, gen, serviceName, decorators);
        }
        public void AddIsMethodResultRecursionTest()
        {
            var dic = new Dictionary<JsonSchema, SchemaImplementationDetails>();
            var schema = new JsonSchema();

            var method = new MockMethod() { ResponseType = "TestSchema" };

            var subresource = new MockResource();
            subresource.Methods.Add("TestMethod", method);

            var resource = new MockResource();
            resource.Resources.Add("Subresource", subresource);
            
            var service = new MockService();
            service.Schemas.Add("TestSchema", new MockSchema { SchemaDetails = schema });
            service.Resources.Add("TestResource", resource);

            // Test parameter validation:
            Assert.Throws<ArgumentNullException>(
                () => ImplementationDetailsGenerator.AddIsMethodResult(null, service, service.Resources.Values));
            Assert.Throws<ArgumentNullException>(
                () => ImplementationDetailsGenerator.AddIsMethodResult(dic, null, service.Resources.Values));
            Assert.Throws<ArgumentNullException>(
                () => ImplementationDetailsGenerator.AddIsMethodResult(dic, service, (IEnumerable<IResource>) null));

            // Test recursive add:
            ImplementationDetailsGenerator.AddIsMethodResult(dic, service, service.Resources.Values);
            Assert.AreEqual(dic.Count, 1);

            var implDetails = dic[schema];
            Assert.IsTrue(implDetails.IsMethodResult);
        }
        public void GenerateRequestClassTest()
        {
            var decorator = new CountingRequestDecorator();
            var generator = new RequestClassGenerator(new IRequestDecorator[] { decorator });
            var decl = new CodeTypeDeclaration();

            // Create a test resource.
            var resource = new MockResource();
            MockMethod method = new MockMethod() { Name = "MethodA" };
            resource.Methods.Add("MethodA", method);

            // Run the generator
            CodeTypeDeclaration newClass = generator.GenerateRequestClass(resource, method, decl, new string[0]);
            Assert.IsNotNull(newClass);
            Assert.AreEqual(1, decorator.TimesCalled);
            Assert.AreEqual(0, newClass.Members.Count);
        }
        public void GenerateSubresourceTest()
        {
            var dec = new SubresourceClassDecorator();
            const string serviceName = "TestService";
            var decorators = new IResourceDecorator[0];

            // Create generators.
            var resourceGen = new ResourceContainerGenerator(new IResourceContainerDecorator[0]);
            var requestGen = new RequestClassGenerator(new IRequestDecorator[0]);

            // Test generation of the nested class
            var subresource = new MockResource { Name = "Sub" };
            CodeTypeDeclaration decl = dec.GenerateSubresource(
                subresource, serviceName, decorators, requestGen, resourceGen, new string[0]);

            Assert.IsNotNull(decl);
            Assert.AreEqual(decl.Name, "SubResource");
        }
        public void GenerateRequestClassDecoratorOrderTest()
        {
            var generator =
                new RequestClassGenerator(
                    new IRequestDecorator[]
                        {
                            new MockRequestDecorator("One"), new MockRequestDecorator("Two"),
                            new MockRequestDecorator("Three")
                        });
            var decl = new CodeTypeDeclaration();
            var resource = new MockResource();
            var method = new MockMethod();

            // Check the order of the generated members.
            var genClass = generator.GenerateRequestClass(resource, method, decl, Enumerable.Empty<string>());
            Assert.AreEqual(3, genClass.Members.Count);
            Assert.AreEqual("One", genClass.Members[0].Name);
            Assert.AreEqual("Two", genClass.Members[1].Name);
            Assert.AreEqual("Three", genClass.Members[2].Name);
        }