diff --git a/src/client/models/parsing-2/parser_data.coffee b/src/client/models/parsing-2/parser_data.coffee index 08885a395..37a5ae3bc 100644 --- a/src/client/models/parsing-2/parser_data.coffee +++ b/src/client/models/parsing-2/parser_data.coffee @@ -26,6 +26,7 @@ module.exports = class ParserData create: (command, type, id=null)-> id ?= _.uniqueId "#{type}-" + @clearCurrent type typeData = @_findOrCreateType type itemData = @_current = typeData['current'] = typeData[id] = id:id, command:command, type:type @@ -37,9 +38,49 @@ module.exports = class ParserData clear: -> @_current = null - @_data = {} + @_data = + mod: {} + modVersion: {} + tutorial: {} + itemGroup: {} + item: {} + multiblock: {} + recipe: {} @_errors = [] + clearCurrent: (type)-> + switch type + when 'mod' + delete @_data.mod.current + delete @_data.modVersion.current + delete @_data.tutorial.current + delete @_data.itemGroup.current + delete @_data.item.current + delete @_data.multiblock.current + delete @_data.recipe.current + when 'modVersion' + delete @_data.modVersion.current + delete @_data.tutorial.current + delete @_data.itemGroup.current + delete @_data.item.current + delete @_data.multiblock.current + delete @_data.recipe.current + when 'tutorial' + delete @_data.tutorial.current + when 'itemGroup' + delete @_data.itemGroup.current + delete @_data.item.current + delete @_data.multiblock.current + delete @_data.recipe.current + when 'item' + delete @_data.item.current + delete @_data.multiblock.current + delete @_data.recipe.current + when 'multiblock' + delete @_data.multiblock.current + when 'recipe' + delete @_data.recipe.current + get: (type, id)-> typeData = @_findOrCreateType type itemData = typeData[id] or null diff --git a/src/client/models/parsing-2/parser_extension.coffee b/src/client/models/parsing-2/parser_extension.coffee index f3e059215..9a42f4254 100644 --- a/src/client/models/parsing-2/parser_extension.coffee +++ b/src/client/models/parsing-2/parser_extension.coffee @@ -55,6 +55,14 @@ module.exports = class ParserExtension return false + incompatibleField: (command, obj, field, otherCommandName)-> + otherCommandName ?= field + if obj[field]? + @data.addError "#{command.name} cannot be used with #{otherCommandName}" + return true + + return false + missingCurrent: (command, type)-> obj = @data.getCurrent type if not obj? @@ -77,6 +85,13 @@ module.exports = class ParserExtension return false + invalidVerb: (command, verb)-> + if not verb in ['mod', 'item'] + @data.addError command, "#{command.name} only applies to either `mod` or `item`" + return true + + return false + tooFewArguments: (command, minimum)-> if command.args.length < minimum @data.addError command, "#{command.name} requires at least #{minimum} arguments" diff --git a/src/client/models/parsing-2/parser_extensions/current_pe_v1.coffee b/src/client/models/parsing-2/parser_extensions/current_pe_v1.coffee index f5d3cfd9e..b3bab06cb 100644 --- a/src/client/models/parsing-2/parser_extensions/current_pe_v1.coffee +++ b/src/client/models/parsing-2/parser_extensions/current_pe_v1.coffee @@ -13,19 +13,13 @@ module.exports = class CurrentParserExtensionV1 extends ParserExtension constructor: (data)-> super data, null, - documentationUrl: @_command_documentationUrl - description: @_command_description - name: @_command_name + description: @_command_description + name: @_command_name + officialUrl: @_command_officialUrl + video: @_command_video # Command Methods ############################################################################## - _command_documentationUrl: (command)-> - current = @data.getCurrent() - return if @duplicateField command, current, 'documentationUrl' - return if @missingArgText command - - current.documentationUrl = command.argText - _command_description: (command)-> current = @data.getCurrent() return if @duplicateField command, current, 'description' @@ -39,3 +33,18 @@ module.exports = class CurrentParserExtensionV1 extends ParserExtension return if @missingArgText command current.name = command.argText + + _command_officialUrl: (command)-> + current = @data.getCurrent() + return if @duplicateField command, current, 'officialUrl' + return if @missingArgText command + + current.officialUrl = command.argText + + _command_video: (command)-> + current = @data.getCurrent() + return if @missingArgs command + return if @tooFewArguments command, 2 + + current.videos ?= [] + current.videos.push youTubeId:command.args[0], caption:command.args[1..].join(', ') diff --git a/src/client/models/parsing-2/parser_extensions/current_pe_v1.test.coffee b/src/client/models/parsing-2/parser_extensions/current_pe_v1.test.coffee index 0b6f2ef5c..8af2ede3b 100644 --- a/src/client/models/parsing-2/parser_extensions/current_pe_v1.test.coffee +++ b/src/client/models/parsing-2/parser_extensions/current_pe_v1.test.coffee @@ -22,13 +22,6 @@ describe 'current_pe_v1.coffee', -> state.create {}, 'alpha' - describe 'documentationUrl', -> - - it 'assigns to the current object', -> - parser.execute name:'documentationUrl', argText:'bravo' - state.getCurrent().documentationUrl.should.equal 'bravo' - state.errors.should.eql [] - describe 'description', -> it 'assigns to the current object', -> @@ -42,3 +35,25 @@ describe 'current_pe_v1.coffee', -> parser.execute name:'name', argText:'bravo' state.getCurrent().name.should.equal 'bravo' state.errors.should.eql [] + + describe 'officialUrl', -> + + it 'assigns to the current object', -> + parser.execute name:'officialUrl', argText:'bravo' + state.getCurrent().officialUrl.should.equal 'bravo' + state.errors.should.eql [] + + describe 'video', -> + + it 'assigns to the current object', -> + parser.execute name:'video', args:['alpha', 'bravo'] + videos = state.getCurrent().videos + videos[0].youTubeId.should.equal 'alpha' + videos[0].caption.should.equal 'bravo' + state.errors.should.eql [] + + it 'can assign multiple videos', -> + parser.execute name:'video', args:['alpha', 'bravo'] + parser.execute name:'video', args:['charlie', 'delta'] + state.getCurrent().videos.length.should.equal 2 + state.errors.should.eql [] diff --git a/src/client/models/parsing-2/parser_extensions/item_pe_v1.coffee b/src/client/models/parsing-2/parser_extensions/item_pe_v1.coffee index 9dbc48efd..474e5b0cd 100644 --- a/src/client/models/parsing-2/parser_extensions/item_pe_v1.coffee +++ b/src/client/models/parsing-2/parser_extensions/item_pe_v1.coffee @@ -15,6 +15,7 @@ module.exports = class ItemParserExtensionV1 extends ParserExtension super data, 'item', gatherable: @_command_gatherable item: @_command_item + update: @_command_update # ParserExtensions Overrides ################################################################### @@ -31,11 +32,10 @@ module.exports = class ItemParserExtensionV1 extends ParserExtension _command_gatherable: (command)-> return if @missingArgText command - return if @missingCurrent command, 'item' item = @data.getCurrent 'item' - return if @duplicateField command, 'gatherable', item + return if @duplicateField command, item, 'gatherable' gatherable = @parseBoolean command, command.argText return unless gatherable? @@ -49,17 +49,19 @@ module.exports = class ItemParserExtensionV1 extends ParserExtension item = @data.create command, 'item', command.argText item.name = command.argText + item.isUpdate = false group = @data.getCurrent 'itemGroup' if group? then item.group = group item.modVersion = @data.getCurrent 'modVersion' - _command_video: (command)-> - return if @missingArgs command - return if @missingCurrent command, 'item' - return if @tooFewArguments command, 2 + _command_update: (command)-> + return if @missingArgText command + return if @missingCurrent command, 'modVersion' + return if @alreadyExists command, 'item', command.argText - item = @data.getCurrent 'item' - item.videos ?= [] - item.videos.push youTubeId:command.args[0], caption:command.args[1..].join(', ') + item = @data.create command, 'item', command.argText + item.name = command.argText + item.isUpdate = true + item.modVersion = @data.getCurrent 'modVersion' diff --git a/src/client/models/parsing-2/parser_extensions/item_pe_v1.test.coffee b/src/client/models/parsing-2/parser_extensions/item_pe_v1.test.coffee index 4a405562d..63603e0c4 100644 --- a/src/client/models/parsing-2/parser_extensions/item_pe_v1.test.coffee +++ b/src/client/models/parsing-2/parser_extensions/item_pe_v1.test.coffee @@ -39,6 +39,16 @@ describe 'item_pe_v1.coffee', -> parser.execute name:'item', argText:'alpha' item = data.getCurrent 'item' item.id.should.equal 'alpha' + item.isUpdate.should.equal false item.name.should.equal 'alpha' item.modVersion.id.should.equal 0 item.group.id.should.equal 2 + data.getErrors().should.eql [] + + describe 'update', -> + + it 'creates an item update', -> + parser.execute name:'update', argText:'alpha' + item = data.getCurrent 'item' + item.isUpdate.should.equal true + data.getErrors().should.eql [] \ No newline at end of file diff --git a/src/client/models/parsing-2/parser_extensions/mod_pe_v1.coffee b/src/client/models/parsing-2/parser_extensions/mod_pe_v1.coffee index d5ac7bd41..ead300e7b 100644 --- a/src/client/models/parsing-2/parser_extensions/mod_pe_v1.coffee +++ b/src/client/models/parsing-2/parser_extensions/mod_pe_v1.coffee @@ -13,10 +13,11 @@ module.exports = class ModParserExtensionV1 extends ParserExtension constructor: (data)-> super data, 'mod', - author: @_command_author - downloadUrl: @_command_downloadUrl - homePageUrl: @_command_homePageUrl - mod: @_command_mod + author: @_command_author + documentationUrl: @_command_documentationUrl + downloadUrl: @_command_downloadUrl + homePageUrl: @_command_homePageUrl + mod: @_command_mod # Command Methods ############################################################################## @@ -29,6 +30,13 @@ module.exports = class ModParserExtensionV1 extends ParserExtension mod.author = command.argText + _command_documentationUrl: (command)-> + current = @data.getCurrent() + return if @duplicateField command, current, 'documentationUrl' + return if @missingArgText command + + current.documentationUrl = command.argText + _command_downloadUrl: (command)-> return if @missingCurrent command, 'mod' @@ -51,4 +59,4 @@ module.exports = class ModParserExtensionV1 extends ParserExtension return if @missingArgText command return if @alreadyExists command, 'mod', command.argText - @data.create command, 'mod', command.argText + @data.create command, 'mod', command.argText \ No newline at end of file diff --git a/src/client/models/parsing-2/parser_extensions/mod_pe_v1.test.coffee b/src/client/models/parsing-2/parser_extensions/mod_pe_v1.test.coffee index f199ae807..c22ae8541 100644 --- a/src/client/models/parsing-2/parser_extensions/mod_pe_v1.test.coffee +++ b/src/client/models/parsing-2/parser_extensions/mod_pe_v1.test.coffee @@ -29,6 +29,13 @@ describe 'mod_pe_v1.coffee', -> data.getCurrent('mod').author.should.equal 'alpha' data.errors.should.eql [] + describe 'documentationUrl', -> + + it 'assigns to the current mod', -> + parser.execute name:'documentationUrl', argText:'alpha' + data.getCurrent('mod').documentationUrl.should.equal 'alpha' + data.errors.should.eql [] + describe 'downloadUrl', -> it 'assigns to the current mod', -> diff --git a/src/client/models/parsing-2/parser_extensions/multiblock_pe_v1.coffee b/src/client/models/parsing-2/parser_extensions/multiblock_pe_v1.coffee new file mode 100644 index 000000000..9ee91521b --- /dev/null +++ b/src/client/models/parsing-2/parser_extensions/multiblock_pe_v1.coffee @@ -0,0 +1,38 @@ +# +# Crafting Guide - multiblock_pe_v1.coffee +# +# Copyright © 2014-2016 by Redwood Labs +# All rights reserved. +# + +ParserExtension = require '../parser_extension' + +######################################################################################################################## + +module.exports = class MultiblockParserExtensionV1 extends ParserExtension + + constructor: (data)-> + super data, 'multiblock', + layer: @_command_layer + multiblock: @_command_multiblock + + # Command Methods ############################################################################## + + _command_layer: (command)-> + return if @missingCurrent command, 'multiblock' + return if @missingArgText command + + multiblock = @data.getCurrent 'multiblock' + multiblock.layers ?= [] + multiblock.layers.push command.argText + + _command_multiblock: (command)-> + return if @missingCurrent command, 'item' + + item = @data.getCurrent 'item' + return if @duplicateField command, item, 'multiblock' + return if @incompatibleField command, item, 'recipe' + return if @incompatibleField command, item, 'gatherable' + + multiblock = @data.create command, 'multiblock' + multiblock.item = item diff --git a/src/client/models/parsing-2/parser_extensions/multiblock_pe_v1.test.coffee b/src/client/models/parsing-2/parser_extensions/multiblock_pe_v1.test.coffee new file mode 100644 index 000000000..8acc8471e --- /dev/null +++ b/src/client/models/parsing-2/parser_extensions/multiblock_pe_v1.test.coffee @@ -0,0 +1,48 @@ +# +# Crafting Guide - multiblock_pe_v1.test.coffee +# +# Copyright © 2014-2016 by Redwood Labs +# All rights reserved. +# + +MultiblockParserExtensionV1 = require './multiblock_pe_v1' +ParserData = require '../parser_data' + +######################################################################################################################## + +parser = data = null + +######################################################################################################################## + +describe 'multiblock_pe_v1.coffee', -> + + beforeEach -> + data = new ParserData + parser = new MultiblockParserExtensionV1 data + + data.create {}, 'item', 1 + + describe 'layer', -> + + it 'creates a new layer in the current multiblock', -> + data.create {}, 'multiblock', 2 + + parser.execute name:'layer', argText:'alpha' + multiblock = data.getCurrent 'multiblock' + multiblock.layers.length.should.equal 1 + multiblock.layers[0].should.equal 'alpha' + + it 'can create multiple layers', -> + data.create {}, 'multiblock', 2 + + parser.execute name:'layer', argText:'alpha' + parser.execute name:'layer', argText:'bravo' + multiblock = data.getCurrent 'multiblock' + multiblock.layers.should.eql ['alpha', 'bravo'] + + describe 'multiblock', -> + + it 'creates a new multiblock', -> + parser.execute name:'multiblock' + multiblock = data.getCurrent 'multiblock' + multiblock.item.id.should.equal 1 \ No newline at end of file diff --git a/src/client/models/parsing-2/parser_extensions/recipe_pe_v1.coffee b/src/client/models/parsing-2/parser_extensions/recipe_pe_v1.coffee index e4d79732b..f5dd49bd1 100644 --- a/src/client/models/parsing-2/parser_extensions/recipe_pe_v1.coffee +++ b/src/client/models/parsing-2/parser_extensions/recipe_pe_v1.coffee @@ -13,12 +13,14 @@ module.exports = class RecipeParserExtensionV1 extends ParserExtension constructor: (data)-> super data, 'recipe', - extras: @_command_extras - input: @_command_input - pattern: @_command_pattern - recipe: @_command_recipe - quantity: @_command_quantity - tools: @_command_tools + extras: @_command_extras + ignoreDuringCrafting: @_command_ignoreDuringCrafting + input: @_command_input + onlyIf: @_command_onlyIf + pattern: @_command_pattern + recipe: @_command_recipe + quantity: @_command_quantity + tools: @_command_tools # Class Methods ################################################################################ @@ -47,14 +49,48 @@ module.exports = class RecipeParserExtensionV1 extends ParserExtension recipe.extras = command.args + _command_ignoreDuringCrafting: (command)-> + return if @missingArgText command + return if @missingCurrent command, 'recipe' + + recipe = @data.getCurrent 'recipe' + return if @duplicateField command, recipe, 'ignoreDuringCrafting' + + ignoreDuringCrafting = @parseBoolean command, command.argText + return unless ignoreDuringCrafting? + + recipe.ignoreDuringCrafting = ignoreDuringCrafting + _command_input: (command)-> return if @missingCurrent command, 'recipe' return if @missingArgs command recipe = @data.getCurrent 'recipe' - return if @duplicateField command, 'input', recipe + multiblock = @data.getCurrent 'multiblock' - recipe.input = (@_parseStack(arg) for arg in command.args) + target = if multiblock? then multiblock else recipe + + return if @duplicateField command, 'input', target + target.input = (@_parseStack(arg) for arg in command.args) + + _command_onlyIf: (command)-> + return if @missingCurrent command, 'recipe' + return if @missingArgText command + + recipe = @data.getCurrent 'recipe' + return if @duplicateField command, recipe, 'condition' + + words = command.argText.split ' ' + inverted = false + if words[0] is 'not' + inverted = true + words.shift() + + verb = words[0] + noun = words[1..].join ' ' + + return if @invalidVerb command, verb + recipe.condition = verb:verb, noun:noun, inverted:inverted _command_pattern: (command)-> return if @missingCurrent command, 'recipe' @@ -66,12 +102,6 @@ module.exports = class RecipeParserExtensionV1 extends ParserExtension recipe.pattern = command.argText - _command_recipe: (command)-> - return if @missingCurrent command, 'item' - - recipe = @data.create command, 'recipe' - recipe.item = @data.getCurrent 'item' - _command_quantity: (command)-> return if @missingCurrent command, 'recipe' return if @missingArgText command @@ -84,6 +114,12 @@ module.exports = class RecipeParserExtensionV1 extends ParserExtension recipe.quantity = value + _command_recipe: (command)-> + return if @missingCurrent command, 'item' + + recipe = @data.create command, 'recipe' + recipe.item = @data.getCurrent 'item' + _command_tools: (command)-> return if @missingCurrent command, 'recipe' return if @missingArgs command diff --git a/src/client/models/parsing-2/parser_extensions/recipe_pe_v1.test.coffee b/src/client/models/parsing-2/parser_extensions/recipe_pe_v1.test.coffee index 60470263b..49d76f314 100644 --- a/src/client/models/parsing-2/parser_extensions/recipe_pe_v1.test.coffee +++ b/src/client/models/parsing-2/parser_extensions/recipe_pe_v1.test.coffee @@ -32,6 +32,16 @@ describe 'recipe_pe_v1.coffee', -> recipe.extras.should.eql ['bravo'] data.errors.should.eql [] + describe 'ignoreDuringCrafting', -> + + it 'assigns to the current recipe', -> + data.create {}, 'recipe' + + parser.execute name:'ignoreDuringCrafting', argText:'yes' + recipe = data.getCurrent 'recipe' + recipe.ignoreDuringCrafting.should.equal true + data.errors.should.eql [] + describe 'input', -> it 'correctly reads a single item', -> @@ -58,6 +68,16 @@ describe 'recipe_pe_v1.coffee', -> recipe.input.should.eql [name:'bravo', quantity:10] data.errors.should.eql [] + describe 'onlyIf', -> + + it 'assigns to the current recipe', -> + data.create {}, 'recipe' + + parser.execute name:'onlyIf', argText:'not mod Alpha' + recipe = data.getCurrent 'recipe' + recipe.condition.should.eql verb:'mod', noun:'Alpha', inverted:true + data.errors.should.eql [] + describe 'pattern', -> it 'assigns to the current recipe', -> @@ -76,14 +96,6 @@ describe 'recipe_pe_v1.coffee', -> expect(recipe.pattern).to.be.undefined (e.message for e in data.errors).should.eql ['invalid pattern: "alpha"'] - describe 'recipe', -> - - it 'creates a new recipe', -> - parser.execute name:'recipe' - recipe = data.getCurrent 'recipe' - recipe.item.id.should.equal 0 - data.errors.should.eql [] - describe 'quantity', -> it 'assigns to the current recipe', -> @@ -94,6 +106,14 @@ describe 'recipe_pe_v1.coffee', -> recipe.quantity.should.equal 42 data.errors.should.eql [] + describe 'recipe', -> + + it 'creates a new recipe', -> + parser.execute name:'recipe' + recipe = data.getCurrent 'recipe' + recipe.item.id.should.equal 0 + data.errors.should.eql [] + describe 'tools', -> it 'assigns to the current recipe', -> diff --git a/src/client/models/parsing-2/parser_extensions/tutorial_pe_v1.coffee b/src/client/models/parsing-2/parser_extensions/tutorial_pe_v1.coffee new file mode 100644 index 000000000..714e6958e --- /dev/null +++ b/src/client/models/parsing-2/parser_extensions/tutorial_pe_v1.coffee @@ -0,0 +1,51 @@ +# +# Crafting Guide - tutorial_pe_v1.coffee +# +# Copyright © 2014-2016 by Redwood Labs +# All rights reserved. +# + +ParserExtension = require '../parser_extension' + +######################################################################################################################## + +module.exports = class TutorialParserExtensionV1 extends ParserExtension + + constructor: (data)-> + super data, 'tutorial', + content: @_command_content + section: @_command_section + title: @_command_title + tutorial: @_command_tutorial + + # Command Methods ############################################################################## + + _command_content: (command)-> + return if @missingCurrent command, 'tutorial' + return if @missingArgText command + + section = @data.getCurrent 'section' + section.content = command.argText + + _command_section: (command)-> + return if @missingCurrent command, 'tutorial' + + section = @data.create command, 'section' + section.tutorial = @data.getCurrent 'tutorial' + + _command_title: (command)-> + return if @missingCurrent command, 'section' + return if @missingArgText command + + section = @data.getCurrent 'section' + return if @duplicateField command, section, 'title' + + section.title = command.argText + + _command_tutorial: (command)-> + return if @missingCurrent command, 'modVersion' + return if @missingArgText command + + tutorial = @data.create command, 'tutorial', command.argText + tutorial.name = command.argText + tutorial.modVersion = @data.getCurrent 'modVersion' diff --git a/src/client/models/parsing-2/parser_extensions/tutorial_pe_v1.test.coffee b/src/client/models/parsing-2/parser_extensions/tutorial_pe_v1.test.coffee new file mode 100644 index 000000000..ac442416d --- /dev/null +++ b/src/client/models/parsing-2/parser_extensions/tutorial_pe_v1.test.coffee @@ -0,0 +1,63 @@ +# +# Crafting Guide - tutorial_pe_v1.test.coffee +# +# Copyright © 2014-2016 by Redwood Labs +# All rights reserved. +# + +TutorialParserExtensionV1 = require './tutorial_pe_v1' +ParserData = require '../parser_data' + +######################################################################################################################## + +parser = data = null + +######################################################################################################################## + +describe 'tutorial_pe_v1.coffee', -> + + beforeEach -> + data = new ParserData + parser = new TutorialParserExtensionV1 data + + data.create {}, 'modVersion', 1 + + describe 'content', -> + + it 'assigns content to the current section', -> + data.create {}, 'tutorial', 2 + data.create {}, 'section', 3 + + parser.execute name:'content', argText:'alpha' + data.errors.should.eql [] + section = data.getCurrent 'section' + section.content.should.equal 'alpha' + + describe 'section', -> + + it 'creates a section in the current tutorial', -> + data.create {}, 'tutorial', 2 + + parser.execute name:'section' + data.errors.should.eql [] + section = data.getCurrent 'section' + section.tutorial.id.should.equal 2 + + describe 'title', -> + + it 'assigns a title to the current tutorial', -> + data.create {}, 'tutorial', 2 + data.create {}, 'section', 3 + + parser.execute name:'title', argText:'alpha' + data.errors.should.eql [] + section = data.getCurrent 'section' + section.title.should.equal 'alpha' + + describe 'tutorial', -> + + it 'creates a new tutorial', -> + parser.execute name:'tutorial', argText:'alpha' + data.errors.should.eql [] + tutorial = data.getCurrent 'tutorial' + tutorial.name.should.equal 'alpha'