From b4505eff2518ccacd98ccd676ceac83e96d20b06 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Mon, 9 Feb 2015 11:30:48 +0530 Subject: [PATCH] Dive into oneOf and groups when expanding mixins --- src/drafter.coffee | 2 +- src/rules/mson-member-type-name.coffee | 22 ++ src/rules/mson-mixin.coffee | 41 +++- test/fixtures/dataStructures.apib | 10 + test/fixtures/dataStructures.ast.json | 267 ++++++++++++++++++++++++- 5 files changed, 329 insertions(+), 13 deletions(-) diff --git a/src/drafter.coffee b/src/drafter.coffee index 5e4b296..8ea0c9d 100644 --- a/src/drafter.coffee +++ b/src/drafter.coffee @@ -41,7 +41,7 @@ class Drafter protagonist.parse source, @config, (error, result) => callback error if error - ruleList = ['mson-inheritance', 'mson-mixin'] + ruleList = ['mson-inheritance', 'mson-mixin', 'mson-member-type-name'] rules = (require './rules/' + rule for rule in ruleList) @dataStructures = {} diff --git a/src/rules/mson-member-type-name.coffee b/src/rules/mson-member-type-name.coffee index 23c1ba9..fe6f86c 100644 --- a/src/rules/mson-member-type-name.coffee +++ b/src/rules/mson-member-type-name.coffee @@ -1,7 +1,29 @@ +rule = require './rule' + module.exports = # Variables + expanded: {} dataStructures: {} + # Given a data structure, expand its member type recusrively + # + # @param name [String] Name of the data structure + # @param dataStructure [Object] Data structure + expandMember: (name, dataStructure) -> + return if @expanded[name] + + # Denote this type as expanded + @expanded[name] = true + init: (dataStructures) -> + @expanded = {} @dataStructures = dataStructures + + # Initiate flags + for name, dataStructure of @dataStructures + @expanded[name] = false + + # Actual expansion + for name, dataStructure of @dataStructures + @expandMember name, dataStructure diff --git a/src/rules/mson-mixin.coffee b/src/rules/mson-mixin.coffee index ea1be3e..b832505 100644 --- a/src/rules/mson-mixin.coffee +++ b/src/rules/mson-mixin.coffee @@ -6,6 +6,35 @@ module.exports = expanded: {} dataStructures: {} + # + # + # @param elements [Object] + # @param sectionOrMember [Object] + diveIntoMember: (elements, sectionOrMember) -> + for member in elements + switch member['class'] + + when 'mixin' + superType = member.content.typeSpecification.name + + # Expand the super type first + @expandMixin superType.literal, @dataStructures[superType.literal] + rule.copyMembers @dataStructures[superType.literal], sectionOrMember + + when 'oneOf', 'group' + memberType = + content: [] + + # Recursively dive into the elements + @diveIntoMember member.content, memberType + + # Replace the original member with out new member + member.content = memberType.content + sectionOrMember.content.push member + + else + sectionOrMember.content.push member + # Given a data structure, expand its mixins recusrively # # @param name [String] Name of the data structure @@ -21,17 +50,7 @@ module.exports = memberTypeSection = content: [] - for member in section.content - if member['class'] is 'mixin' - - # Expand the super type first - superType = member.content.typeSpecification.name - @expandMixin superType.literal, @dataStructures[superType.literal] - - rule.copyMembers @dataStructures[superType.literal], memberTypeSection - - else - memberTypeSection.content.push member + @diveIntoMember section.content, memberTypeSection # Replace section content with the new content section.content = memberTypeSection.content diff --git a/test/fixtures/dataStructures.apib b/test/fixtures/dataStructures.apib index b543425..5f4d2d2 100644 --- a/test/fixtures/dataStructures.apib +++ b/test/fixtures/dataStructures.apib @@ -37,3 +37,13 @@ A clone of Coupon Base to be used for testing ## Timestamp Clone (Timestamp) A clone of timestamp to be used for testing + +## Subscription ++ id: 1000 (number) ++ plan: 'Startup' (string) - Subscription plan name ++ coupon (Coupon Base) - Coupon represting any existing discounts used by the customer during the subscription ++ One Of + + Include Timestamps + + Properties + + modified_at (Timestamp) + + Include (Legacy Timestamps) diff --git a/test/fixtures/dataStructures.ast.json b/test/fixtures/dataStructures.ast.json index 910534c..44a9669 100644 --- a/test/fixtures/dataStructures.ast.json +++ b/test/fixtures/dataStructures.ast.json @@ -569,7 +569,272 @@ "sections": [ { "class": "blockDescription", - "content": "A clone of timestamp to be used for testing\n" + "content": "A clone of timestamp to be used for testing\n\n" + } + ] + }, + { + "element": "dataStructure", + "name": { + "literal": "Subscription", + "variable": false + }, + "typeDefinition": { + "typeSpecification": { + "name": null, + "nestedTypes": [] + }, + "attributes": [] + }, + "sections": [ + { + "class": "memberType", + "content": [ + { + "content": { + "name": { + "literal": "id" + }, + "description": "", + "valueDefinition": { + "values": [ + { + "literal": "1000", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "number", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "plan" + }, + "description": "Subscription plan name", + "valueDefinition": { + "values": [ + { + "literal": "'Startup'", + "variable": false + } + ], + "typeDefinition": { + "typeSpecification": { + "name": "string", + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "coupon" + }, + "description": "Coupon represting any existing discounts used by the customer during the subscription", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Coupon Base", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": [ + { + "content": { + "name": { + "literal": "created" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Timestamp", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "modified" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Timestamp", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Timestamp", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "updated_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Timestamp", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": [ + { + "content": { + "name": { + "literal": "modified_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Timestamp", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "created_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Timestamp", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + }, + { + "content": { + "name": { + "literal": "updated_at" + }, + "description": "", + "valueDefinition": { + "values": [], + "typeDefinition": { + "typeSpecification": { + "name": { + "literal": "Timestamp", + "variable": false + }, + "nestedTypes": [] + }, + "attributes": [] + } + }, + "sections": [] + }, + "class": "property" + } + ], + "class": "group" + } + ], + "class": "oneOf" + } + ] } ] }