From 119c28e656c25539cb97f1f04d52e0e13ca867d1 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Sun, 29 Mar 2015 18:37:37 +0530 Subject: [PATCH] Move nested types as value members when resolving data structures --- src/drafter.coffee | 9 +- src/rules/mson-inheritance.coffee | 35 ++ test/fixtures/dataStructures.ast.json | 820 +++++++++++++++++++++++++- 3 files changed, 842 insertions(+), 22 deletions(-) diff --git a/src/drafter.coffee b/src/drafter.coffee index 08297f1..04395db 100644 --- a/src/drafter.coffee +++ b/src/drafter.coffee @@ -174,8 +174,9 @@ class Drafter # @param node [Object] A node of API Blueprint # @param rules [Array] List of rules to apply # @param elementTye [String] The element type of the node - # @param parent [Object] Parent node's content of which the current node is a part of - expandNode: (node, rules, elementType, parentContent) -> + # @param parentContent [Object] Parent node's content of which the current node is a part of + # @param parentElementType [String] The element type of the parent node + expandNode: (node, rules, elementType, parentContent, parentElementType) -> elementType ?= node.element # On root node, Gather data structures first before applying rules to any of the children nodes @@ -219,7 +220,7 @@ class Drafter rule[elementType].call rule, newNode if elementType in Object.keys(rule) # Append resolved data structures - if elementType is 'dataStructure' and not deepEqual node, newNode + if parentElementType not in ['resource', 'blueprint'] and elementType is 'dataStructure' and not deepEqual node, newNode newNode.element = 'resolvedDataStructure' parentContent.push newNode @@ -236,7 +237,7 @@ class Drafter @expandNode response, rules, 'payload' for response in node.responses if node.content and Array.isArray node.content - @expandNode element, rules, null, node.content for element in node.content + @expandNode element, rules, null, node.content, elementType for element in node.content # Reconstruct deprecated resource groups key from elements # diff --git a/src/rules/mson-inheritance.coffee b/src/rules/mson-inheritance.coffee index 3d8bd36..0e8c11a 100644 --- a/src/rules/mson-inheritance.coffee +++ b/src/rules/mson-inheritance.coffee @@ -28,6 +28,41 @@ module.exports = # Check for inheritance superType = dataStructure.typeDefinition.typeSpecification.name + # If super type is array and if it has nested type, append them as value members only if there are no value members + if superType is 'array' + nestedTypes = dataStructure.typeDefinition.typeSpecification.nestedTypes + valueMembersExist = false + + for section in dataStructure.sections + if section['class'] is 'memberType' + valueMembersExist = true + + if not valueMembersExist and nestedTypes.length + memberTypeSection = + content: [] + + memberTypeSection['class'] = 'memberType' + + for nestedType in nestedTypes + valueMember = + content: + description: '' + valueDefinition: + values: [] + typeDefinition: + typeSpecification: + name: nestedType, + nestedTypes: [] + attributes: [] + sections: [] + + valueMember['class'] = 'value' + memberTypeSection.content.push valueMember + + # Push the value members + dataStructure.sections.push memberTypeSection + dataStructure.typeDefinition.typeSpecification.nestedTypes = [] + if superType is null or typeof superType isnt 'object' or not superType?.literal return @expanded[superType] = true diff --git a/test/fixtures/dataStructures.ast.json b/test/fixtures/dataStructures.ast.json index 7005149..550e30d 100644 --- a/test/fixtures/dataStructures.ast.json +++ b/test/fixtures/dataStructures.ast.json @@ -546,8 +546,8 @@ "value": "application/json" } ], - "body": "", - "schema": "", + "body": "[{\"id\":\"250FF\",\"percent_off\":25,\"redeem_by\":null,\"created\":null,\"modified\":null,\"created_at\":null,\"updated_at\":null}]", + "schema": "{\"type\":\"array\",\"$schema\":\"http://json-schema.org/draft-04/schema#\"}", "content": [ { "element": "dataStructure", @@ -570,16 +570,209 @@ "typeDefinition": { "typeSpecification": { "name": "array", - "nestedTypes": [ - { - "literal": "Coupon", - "variable": false - } - ] + "nestedTypes": [] }, "attributes": [] }, - "sections": [] + "sections": [ + { + "content": [ + { + "content": { + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "object", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [ + { + "content": [ + { + "content": { + "name": { + "literal": "id" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "250FF", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "string", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "percent_off" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "25", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [ + { + "class": "blockDescription", + "content": "A positive integer between 1 and 100 that represents the discount the coupon will apply.\n" + } + ] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "redeem_by" + }, + "description": "Date after which the coupon can no longer be redeemed", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "modified" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "updated_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + } + ], + "class": "memberType" + } + ] + }, + "class": "value" + } + ], + "class": "memberType" + } + ] + }, + { + "element": "resolvedAsset", + "attributes": { + "role": "bodyExample" + }, + "content": "[{\"id\":\"250FF\",\"percent_off\":25,\"redeem_by\":null,\"created\":null,\"modified\":null,\"created_at\":null,\"updated_at\":null}]" + }, + { + "element": "resolvedAsset", + "attributes": { + "role": "bodySchema" + }, + "content": "{\"type\":\"array\",\"$schema\":\"http://json-schema.org/draft-04/schema#\"}" } ] } @@ -1037,6 +1230,205 @@ "attributes": [] }, "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": { + "literal": "Coupons", + "variable": false + }, + "typeDefinition": { + "typeSpecification": { + "name": "array", + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [ + { + "content": [ + { + "content": { + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "object", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [ + { + "content": [ + { + "content": { + "name": { + "literal": "id" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "250FF", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "string", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "percent_off" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "25", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [ + { + "class": "blockDescription", + "content": "A positive integer between 1 and 100 that represents the discount the coupon will apply.\n" + } + ] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "redeem_by" + }, + "description": "Date after which the coupon can no longer be redeemed", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "modified" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "updated_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + } + ], + "class": "memberType" + } + ] + }, + "class": "value" + } + ], + "class": "memberType" + } + ] } ] } @@ -3105,8 +3497,8 @@ "value": "application/json" } ], - "body": "", - "schema": "", + "body": "[{\"id\":\"250FF\",\"percent_off\":25,\"redeem_by\":null,\"created\":null,\"modified\":null,\"created_at\":null,\"updated_at\":null}]", + "schema": "{\"type\":\"array\",\"$schema\":\"http://json-schema.org/draft-04/schema#\"}", "content": [ { "element": "dataStructure", @@ -3129,16 +3521,209 @@ "typeDefinition": { "typeSpecification": { "name": "array", - "nestedTypes": [ - { - "literal": "Coupon", - "variable": false - } - ] + "nestedTypes": [] }, "attributes": [] }, - "sections": [] + "sections": [ + { + "content": [ + { + "content": { + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "object", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [ + { + "content": [ + { + "content": { + "name": { + "literal": "id" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "250FF", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "string", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "percent_off" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "25", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [ + { + "class": "blockDescription", + "content": "A positive integer between 1 and 100 that represents the discount the coupon will apply.\n" + } + ] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "redeem_by" + }, + "description": "Date after which the coupon can no longer be redeemed", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "modified" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "updated_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + } + ], + "class": "memberType" + } + ] + }, + "class": "value" + } + ], + "class": "memberType" + } + ] + }, + { + "element": "resolvedAsset", + "attributes": { + "role": "bodyExample" + }, + "content": "[{\"id\":\"250FF\",\"percent_off\":25,\"redeem_by\":null,\"created\":null,\"modified\":null,\"created_at\":null,\"updated_at\":null}]" + }, + { + "element": "resolvedAsset", + "attributes": { + "role": "bodySchema" + }, + "content": "{\"type\":\"array\",\"$schema\":\"http://json-schema.org/draft-04/schema#\"}" } ] } @@ -3596,6 +4181,205 @@ "attributes": [] }, "sections": [] + }, + { + "element": "resolvedDataStructure", + "name": { + "literal": "Coupons", + "variable": false + }, + "typeDefinition": { + "typeSpecification": { + "name": "array", + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [ + { + "content": [ + { + "content": { + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "object", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [ + { + "content": [ + { + "content": { + "name": { + "literal": "id" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "250FF", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "string", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "percent_off" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "25", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [ + { + "class": "blockDescription", + "content": "A positive integer between 1 and 100 that represents the discount the coupon will apply.\n" + } + ] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "redeem_by" + }, + "description": "Date after which the coupon can no longer be redeemed", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "modified" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "updated_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + } + ], + "class": "memberType" + } + ] + }, + "class": "value" + } + ], + "class": "memberType" + } + ] } ] }