Revert local storage change & refactor parser V1

* Revert the local storage change as it ties model objects to global
  state and makes testing impossible. It will be necessary to redo
  that feature differently
* Refactor the parser versions to move V1 into its own set of files
This commit is contained in:
Andrew Miner
2015-01-13 09:44:13 -08:00
parent 47c7cf693a
commit 823df84924
10 changed files with 397 additions and 397 deletions
-6
View File
@@ -13,8 +13,6 @@ Inventory = require './inventory'
module.exports = class CraftingPlan extends BaseModel
constructor: (attributes={}, options={})->
options.storage ?= window.localStorage
if not attributes.modPack then throw new Error 'modPack is required'
attributes.includingTools ?= false
super attributes, options
@@ -29,10 +27,6 @@ module.exports = class CraftingPlan extends BaseModel
@want.on 'change', => @craft()
@modPack.on 'change', => @craft()
value = options.storage.getItem('includingTools')
if value? then @includingTools = value is 'true'
@on 'change:includingTools', => @onIncludingToolsChanged()
@clear()
# Public Methods ###############################################################################
-8
View File
@@ -25,14 +25,6 @@ module.exports = class ModVersion extends BaseModel
attributes.slug ?= _.slugify attributes.name
super attributes, options
enabled = options.storage.getItem("#{@slug}.enabled")
if enabled?
logger.debug "loading #{@slug}.enabled as #{@enabled}"
@enabled = enabled is 'true'
@on 'change:enabled', =>
logger.debug "saving #{@slug}.enabled as #{@enabled}"
options.storage.setItem "#{@slug}.enabled", "#{@enabled}"
# Public Methods ###############################################################################
addItem: (item)->
+1 -214
View File
@@ -5,11 +5,8 @@ Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
Item = require './item'
Logger = require '../logger'
ModVersion = require './mod_version'
Recipe = require './recipe'
Stack = require './stack'
V1 = require './mod_version_parsers/v1'
########################################################################################################################
@@ -42,213 +39,3 @@ module.exports = class ModVersionParser
if not parser? then throw new Error "version #{dataVersion} is not supported"
return parser.unparse modVersion
########################################################################################################################
module.exports.V1 = class V1
constructor: ->
@_errorLocation = 'the header information'
parse: (data)->
return @_parseModVersion data
unparse: (modVersion)->
@modVersion = modVersion
text = @_unparseModVersion modVersion
@modVersion = null
return text
# Private Methods ##############################################################################
_findOrCreateItem: (name)->
item = @modVersion.findItemByName name
if not item?
item = new Item name:name
@modVersion.addItem item
@modVersion.registerSlug item.slug, item.name
return item
_parseModVersion: (data)->
if not data? then throw new Error 'mod description data is missing'
if not data.name? then throw new Error 'name is required'
if not data.version? then throw new Error 'version is required'
if not _.isArray(data.recipes) then throw new Error 'recipes must be an array'
@modVersion = modVersion = new ModVersion name:data.name, version:data.version
modVersion.description = data.description or ''
@_parseRawMaterials data.raw_materials
for index in [0...data.recipes.length]
@_errorLocation = "recipe #{index + 1}"
recipeData = data.recipes[index]
recipe = @_parseRecipe recipeData
recipe._originalIndex = index
@modVersion = null
return modVersion
_parseRawMaterials: (data)->
return unless data? and data.length > 0
results = []
for name in data
item = @_findOrCreateItem name
item.isGatherable = true
results.push item
_parseRecipe: (data)->
if not data? then throw new Error "recipe data is missing for #{@_errorLocation}"
if not data.output? then throw new Error "#{@_errorLocation} is missing output"
data.output = if _.isArray(data.output) then data.output else [data.output]
names = (e for e in _.flatten(data.output) when _.isString(e))
if names.length is 0 then throw new Error "#{@_errorLocation} has an empty output list"
item = @_findOrCreateItem names[0]
@_errorLocation = "recipe for #{item.name}"
if not data.input? then throw new Error "#{@_errorLocation} is missing input"
data.tools ?= []
attributes =
item: item,
output: @_parseStackList(data.output, field:'output', canBeEmpty:false)
input: @_parseStackList(data.input, field:'input', canBeEmpty:true)
tools: @_parseStackList(data.tools, field:'tools', canBeEmpty:true)
attributes.pattern = data.pattern if data.pattern?
recipe = new Recipe attributes
item.addRecipe recipe
return recipe
_parseStack: (data, options={})->
errorBase = "#{options.field} element #{options.index} for #{@_errorLocation}"
if not data? then throw new Error "#{errorBase} is missing"
if _.isString(data) then data = [1, data]
if not _.isArray(data) then throw new Error "#{errorBase} must be an array"
if data.length is 1 then data.unshift 1
if data.length isnt 2 then throw new Error "#{errorBase} must have at least one element"
if not _.isNumber(data[0]) then throw new Error "#{errorBase} must start with a number"
name = data[1]
slug = _.slugify name
@modVersion.registerSlug slug, name
return new Stack itemSlug:slug, quantity:data[0]
_parseStackList: (data, options={})->
if not data? then throw new Error "#{@_errorLocation} must have an #{options.field} field"
if not _.isArray(data) then data = [data]
if data.length is 0 and not options.canBeEmpty
throw new Error "#{options.field} for #{@_errorLocation} cannot be empty"
result = []
for index in [0...data.length]
stackData = data[index]
result.push @_parseStack stackData, field:options.field, index:index
return result
# Un-parsing Methods ###########################################################################
_unparseModVersion: (modVersion)->
result = []
result.push '{\n'
result.push ' "dataVersion": 1,\n'
result.push ' "name": "' + modVersion.name + '",\n'
result.push ' "version": "' + modVersion.version + '",\n'
if modVersion.description.length > 0
result.push ' "description": "' + modVersion.description + '",\n'
rawMaterials = (item.name for slug, item of modVersion.items when item.isGatherable)
rawMaterials.sort()
if rawMaterials.length > 0
result.push ' "raw_materials": [\n'
firstItem = true
for material in rawMaterials
if not firstItem then result.push ',\n'
result.push ' "' + material + '"'
firstItem = false
result.push '\n ],\n'
result.push ' "recipes": [\n'
items = (item for slug, item of modVersion.items when item.isCraftable)
items.sort (a, b)-> a.compareTo b
firstItem = true
for item in items
for recipe in item.recipes
result.push if firstItem then ' {\n' else ' }, {\n'
@_unparseRecipe recipe, result
firstItem = false
result.push ' }\n'
result.push ' ]\n'
result.push '}'
return result.join ''
_unparseRecipe: (recipe, result=[])->
result.push ' "output": '
@_unparseStackList recipe.output, result, sort:false
if recipe.input.length > 0
result.push ',\n'
result.push ' "input": '
@_unparseStackList recipe.input, result
if recipe.pattern?
result.push ',\n'
result.push ' "pattern": "'
result.push recipe.pattern
result.push '"'
if recipe.tools.length > 0
result.push ',\n'
result.push ' "tools": '
@_unparseStackList recipe.tools, result
result.push '\n'
return result
_unparseStackList: (stackList, result, options={})->
options.sort ?= true
if stackList.length is 0
result.push '[]'
else if stackList.length is 1
stack = stackList[0]
if stack.quantity is 1
result.push '"' + @modVersion.findName(stack.itemSlug) + '"'
else
result.push '[[' + stack.quantity + ', "' + @modVersion.findName(stack.itemSlug) + '"]]'
else
result.push '['
stacks = stackList.slice()
if options.sort
stacks.sort (a, b)->
if a.quantity isnt b.quantity
return if a.quantity > b.quantity then -1 else +1
if a.itemSlug isnt b.itemSlug
return if a.itemSlug < b.itemSlug then -1 else +1
return 0
firstItem = true
for stack in stacks
result.push ', ' if not firstItem
if stack.quantity is 1
result.push '"' + @modVersion.findName(stack.itemSlug) + '"'
else
result.push '[' + stack.quantity + ', "' + @modVersion.findName(stack.itemSlug) + '"]'
firstItem = false
result.push ']'
return result
@@ -0,0 +1,228 @@
###
Crafting Guide - mod_version_parsers/v1.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
Item = require '../item'
ModVersion = require '../mod_version'
Recipe = require '../recipe'
Stack = require '../stack'
########################################################################################################################
module.exports = class V1
constructor: ->
@_errorLocation = 'the header information'
parse: (data)->
return @_parseModVersion data
unparse: (modVersion)->
@modVersion = modVersion
text = @_unparseModVersion modVersion
@modVersion = null
return text
# Private Methods ##############################################################################
_findOrCreateItem: (name)->
item = @modVersion.findItemByName name
if not item?
item = new Item name:name
@modVersion.addItem item
@modVersion.registerSlug item.slug, item.name
return item
_parseModVersion: (data)->
if not data? then throw new Error 'mod description data is missing'
if not data.name? then throw new Error 'name is required'
if not data.version? then throw new Error 'version is required'
if not _.isArray(data.recipes) then throw new Error 'recipes must be an array'
@modVersion = modVersion = new ModVersion name:data.name, version:data.version
modVersion.description = data.description or ''
@_parseRawMaterials data.raw_materials
for index in [0...data.recipes.length]
@_errorLocation = "recipe #{index + 1}"
recipeData = data.recipes[index]
recipe = @_parseRecipe recipeData
recipe._originalIndex = index
@modVersion = null
return modVersion
_parseRawMaterials: (data)->
return unless data? and data.length > 0
results = []
for name in data
item = @_findOrCreateItem name
item.isGatherable = true
results.push item
_parseRecipe: (data)->
if not data? then throw new Error "recipe data is missing for #{@_errorLocation}"
if not data.output? then throw new Error "#{@_errorLocation} is missing output"
data.output = if _.isArray(data.output) then data.output else [data.output]
names = (e for e in _.flatten(data.output) when _.isString(e))
if names.length is 0 then throw new Error "#{@_errorLocation} has an empty output list"
item = @_findOrCreateItem names[0]
@_errorLocation = "recipe for #{item.name}"
if not data.input? then throw new Error "#{@_errorLocation} is missing input"
data.tools ?= []
attributes =
item: item,
output: @_parseStackList(data.output, field:'output', canBeEmpty:false)
input: @_parseStackList(data.input, field:'input', canBeEmpty:true)
tools: @_parseStackList(data.tools, field:'tools', canBeEmpty:true)
attributes.pattern = data.pattern if data.pattern?
recipe = new Recipe attributes
item.addRecipe recipe
return recipe
_parseStack: (data, options={})->
errorBase = "#{options.field} element #{options.index} for #{@_errorLocation}"
if not data? then throw new Error "#{errorBase} is missing"
if _.isString(data) then data = [1, data]
if not _.isArray(data) then throw new Error "#{errorBase} must be an array"
if data.length is 1 then data.unshift 1
if data.length isnt 2 then throw new Error "#{errorBase} must have at least one element"
if not _.isNumber(data[0]) then throw new Error "#{errorBase} must start with a number"
name = data[1]
slug = _.slugify name
@modVersion.registerSlug slug, name
return new Stack itemSlug:slug, quantity:data[0]
_parseStackList: (data, options={})->
if not data? then throw new Error "#{@_errorLocation} must have an #{options.field} field"
if not _.isArray(data) then data = [data]
if data.length is 0 and not options.canBeEmpty
throw new Error "#{options.field} for #{@_errorLocation} cannot be empty"
result = []
for index in [0...data.length]
stackData = data[index]
result.push @_parseStack stackData, field:options.field, index:index
return result
# Un-parsing Methods ###########################################################################
_unparseModVersion: (modVersion)->
result = []
result.push '{\n'
result.push ' "dataVersion": 1,\n'
result.push ' "name": "' + modVersion.name + '",\n'
result.push ' "version": "' + modVersion.version + '",\n'
if modVersion.description.length > 0
result.push ' "description": "' + modVersion.description + '",\n'
rawMaterials = (item.name for slug, item of modVersion.items when item.isGatherable)
rawMaterials.sort()
if rawMaterials.length > 0
result.push ' "raw_materials": [\n'
firstItem = true
for material in rawMaterials
if not firstItem then result.push ',\n'
result.push ' "' + material + '"'
firstItem = false
result.push '\n ],\n'
result.push ' "recipes": [\n'
items = (item for slug, item of modVersion.items when item.isCraftable)
items.sort (a, b)-> a.compareTo b
firstItem = true
for item in items
for recipe in item.recipes
result.push if firstItem then ' {\n' else ' }, {\n'
@_unparseRecipe recipe, result
firstItem = false
result.push ' }\n'
result.push ' ]\n'
result.push '}'
return result.join ''
_unparseRecipe: (recipe, result=[])->
result.push ' "output": '
@_unparseStackList recipe.output, result, sort:false
if recipe.input.length > 0
result.push ',\n'
result.push ' "input": '
@_unparseStackList recipe.input, result
if recipe.pattern?
result.push ',\n'
result.push ' "pattern": "'
result.push recipe.pattern
result.push '"'
if recipe.tools.length > 0
result.push ',\n'
result.push ' "tools": '
@_unparseStackList recipe.tools, result
result.push '\n'
return result
_unparseStackList: (stackList, result, options={})->
options.sort ?= true
if stackList.length is 0
result.push '[]'
else if stackList.length is 1
stack = stackList[0]
if stack.quantity is 1
result.push '"' + @modVersion.findName(stack.itemSlug) + '"'
else
result.push '[[' + stack.quantity + ', "' + @modVersion.findName(stack.itemSlug) + '"]]'
else
result.push '['
stacks = stackList.slice()
if options.sort
stacks.sort (a, b)->
if a.quantity isnt b.quantity
return if a.quantity > b.quantity then -1 else +1
if a.itemSlug isnt b.itemSlug
return if a.itemSlug < b.itemSlug then -1 else +1
return 0
firstItem = true
for stack in stacks
result.push ', ' if not firstItem
if stack.quantity is 1
result.push '"' + @modVersion.findName(stack.itemSlug) + '"'
else
result.push '[' + stack.quantity + ', "' + @modVersion.findName(stack.itemSlug) + '"]'
firstItem = false
result.push ']'
return result
########################################################################################################################
module.exports.V2 = class V2 extends V1
constructor: ->
@_errorLocation = 'the header information'
+1 -1
View File
@@ -32,7 +32,7 @@ describe 'CraftingPlan', ->
]
}
plan = new CraftingPlan modPack:modPack
plan = new CraftingPlan modPack:modPack, includingTools:false
describe 'craft', ->
+3 -3
View File
@@ -18,16 +18,16 @@ buildcraft = industrialCraft = minecraft = modPack = null
describe 'ModPack', ->
beforeEach ->
minecraft = new ModVersion name:'Minecraft', version:'1.7.10'
minecraft = new ModVersion name:'Minecraft', version:'1.7.10', enabled:true
minecraft.addItem new Item name:'Wool'
minecraft.addItem new Item name:'Bed', recipes:['']
minecraft.registerSlug 'iron_chestplate', 'Iron Chestplate'
buildcraft = new ModVersion name:'Buildcraft', version:'4.0'
buildcraft = new ModVersion name:'Buildcraft', version:'4.0', enabled:false
buildcraft.addItem new Item name:'Stone Gear', recipes:['']
buildcraft.addItem new Item name:'Bed', recipes:['']
industrialCraft = new ModVersion name:'Industrial Craft', version:'2.0'
industrialCraft = new ModVersion name:'Industrial Craft', version:'2.0', enabled:false
industrialCraft.addItem new Item name:'Resin'
industrialCraft.addItem new Item name:'Rubber', recipes:['']
+1 -1
View File
@@ -29,7 +29,7 @@ describe 'ModVersion', ->
it 'supplies default values', ->
modVersion.description.should.equal ''
modVersion.items.should.eql {}
modVersion.enabled.should.be.false
modVersion.enabled.should.be.true
describe 'addItem', ->
-162
View File
@@ -1,162 +0,0 @@
###
Crafting Guide - v1.test.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
Item = require '../src/scripts/models/item'
ModVersion = require '../src/scripts/models/mod_version'
ModVersionParser = require '../src/scripts/models/mod_version_parser'
########################################################################################################################
modVersion = parser = null
########################################################################################################################
describe 'ModVersionParser', ->
describe "V1", ->
beforeEach ->
parser = new ModVersionParser.V1
modVersion = parser.modVersion = new ModVersion name:'Test', version:'0.0'
describe '_parseModVersion', ->
it 'requires a mod_name', ->
data = version:'1.0', items:[]
expect(-> parser._parseModVersion data).to.throw Error, 'name is required'
it 'requires a mod_version', ->
data = name:'Empty', items:[]
expect(-> parser._parseModVersion data).to.throw Error, 'version is required'
it 'can parse an empty modVersion', ->
data =
name: 'Empty'
version: '1.0'
recipes: []
modVersion = parser._parseModVersion data
modVersion.name.should.equal 'Empty'
modVersion.version.should.equal '1.0'
it 'can parse a non-empty mod version', ->
data =
name: 'Minecraft'
version: '1.7.10'
recipes: [
{ input:'Sugar Cane', output:'Sugar' }
{ input:[[3, 'Wool'], [3, 'Planks']], tools:'Crafting Table', output:'Bed' }
]
modVersion = parser._parseModVersion data
modVersion.name.should.equal 'Minecraft'
modVersion.version.should.equal '1.7.10'
slugs = (slug for slug, item of modVersion.items).sort()
slugs.should.eql ['bed', 'sugar']
describe '_parseRawMaterials', ->
it 'skips the section when missing', ->
parser._parseRawMaterials null
_.keys(modVersion._items).length.should.equal 0
it 'skips the section when empty', ->
parser._parseRawMaterials []
_.keys(modVersion._items).length.should.equal 0
it 'adds items marked as gatherable', ->
parser._parseRawMaterials ['Wool']
modVersion.items['wool'].isGatherable.should.be.true
it 'marks an existing item as gatherable', ->
modVersion.addItem new Item name:'Wool'
modVersion.items['wool'].isGatherable.should.be.false
parser._parseRawMaterials ['Wool']
modVersion.items['wool'].isGatherable.should.be.true
it 'registers the names of the items', ->
parser._parseRawMaterials ['Wool']
modVersion.names['wool'].should.equal 'Wool'
describe '_parseRecipe', ->
it 'requires output to be defined', ->
parser._errorLocation = 'boat'
test = -> parser._parseRecipe {input:'wool'}
expect(test).to.throw Error, 'boat is missing output'
it 'requires input to be defined', ->
test = -> parser._parseRecipe {output:'wool'}
expect(test).to.throw Error, 'recipe for wool is missing input'
it 'can parse a regular recipe', ->
data =
output: 'bed'
input: [[3, 'planks'], [3, 'wool']]
tools: 'crafting table'
recipe = parser._parseRecipe data
(stack.itemSlug for stack in recipe.output).should.eql ['bed']
(stack.itemSlug for stack in recipe.input).sort().should.eql ['planks', 'wool']
(stack.itemSlug for stack in recipe.tools).should.eql ['crafting_table']
it 'can parse a recipe without tools', ->
recipe = parser._parseRecipe {output:'sugar', input:'sugar cane'}
(stack.itemSlug for stack in recipe.output).should.eql ['sugar']
(stack.itemSlug for stack in recipe.input).sort().should.eql ['sugar_cane']
(stack.itemSlug for stack in recipe.tools).should.eql []
it 'registers all names', ->
data =
output: 'Bed'
input: [[3, 'Oak Wood Planks'], [3, 'Wool']]
tools: 'Crafting Table'
parser._parseRecipe data
_.keys(modVersion.names).sort().should.eql ['bed', 'crafting_table', 'oak_wood_planks', 'wool']
describe '_parseStack', ->
it 'requires the array to have at least one element', ->
parser._errorLocation = 'boat'
options = index:1, field:'output'
expect(-> parser._parseStack([], options)).to.throw Error,
"output element 1 for boat must have at least one element"
it 'can fill in a missing number', ->
stack = parser._parseStack 'boat'
stack.itemSlug.should.equal 'boat'
stack.quantity.should.equal 1
stack2 = parser._parseStack ['boat']
stack2.itemSlug.should.equal 'boat'
stack2.quantity.should.equal 1
it 'requires the data to start with a number', ->
parser._errorLocation = 'boat'
options = index:1, field:'output'
expect(-> parser._parseStack(['2', 'wool'], options)).to.throw Error,
"output element 1 for boat must start with a number"
it 'can parse a basic item', ->
stack = parser._parseStack [2, 'wool']
stack.constructor.name.should.equal 'Stack'
describe '_parseStackList', ->
it 'can promote a single item to a list', ->
list = parser._parseStackList 'boat'
(stack.itemSlug for stack in list).should.eql ['boat']
it 'can require a list to be non-empty', ->
parser._errorLocation = 'boat'
options = field:'output', canBeEmpty:false
expect(-> parser._parseStackList [], options).to.throw Error, 'output for boat cannot be empty'
it 'can allow an empty list', ->
list = parser._parseStackList [], canBeEmpty:true
list.length.should.equal 0
it 'can parse a non-empty list', ->
list = parser._parseStackList [[3, 'plank'], [3, 'wool']]
(stack.itemSlug for stack in list).sort().should.eql ['plank', 'wool']
+160
View File
@@ -0,0 +1,160 @@
###
Crafting Guide - mod_version_parsers/v1.test.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
Item = require '../../src/scripts/models/item'
ModVersion = require '../../src/scripts/models/mod_version'
V1 = require '../../src/scripts/models/mod_version_parsers/v1'
########################################################################################################################
modVersion = parser = null
########################################################################################################################
describe "V1", ->
beforeEach ->
parser = new V1
modVersion = parser.modVersion = new ModVersion name:'Test', version:'0.0'
describe '_parseModVersion', ->
it 'requires a mod_name', ->
data = version:'1.0', items:[]
expect(-> parser._parseModVersion data).to.throw Error, 'name is required'
it 'requires a mod_version', ->
data = name:'Empty', items:[]
expect(-> parser._parseModVersion data).to.throw Error, 'version is required'
it 'can parse an empty modVersion', ->
data =
name: 'Empty'
version: '1.0'
recipes: []
modVersion = parser._parseModVersion data
modVersion.name.should.equal 'Empty'
modVersion.version.should.equal '1.0'
it 'can parse a non-empty mod version', ->
data =
name: 'Minecraft'
version: '1.7.10'
recipes: [
{ input:'Sugar Cane', output:'Sugar' }
{ input:[[3, 'Wool'], [3, 'Planks']], tools:'Crafting Table', output:'Bed' }
]
modVersion = parser._parseModVersion data
modVersion.name.should.equal 'Minecraft'
modVersion.version.should.equal '1.7.10'
slugs = (slug for slug, item of modVersion.items).sort()
slugs.should.eql ['bed', 'sugar']
describe '_parseRawMaterials', ->
it 'skips the section when missing', ->
parser._parseRawMaterials null
_.keys(modVersion._items).length.should.equal 0
it 'skips the section when empty', ->
parser._parseRawMaterials []
_.keys(modVersion._items).length.should.equal 0
it 'adds items marked as gatherable', ->
parser._parseRawMaterials ['Wool']
modVersion.items['wool'].isGatherable.should.be.true
it 'marks an existing item as gatherable', ->
modVersion.addItem new Item name:'Wool'
modVersion.items['wool'].isGatherable.should.be.false
parser._parseRawMaterials ['Wool']
modVersion.items['wool'].isGatherable.should.be.true
it 'registers the names of the items', ->
parser._parseRawMaterials ['Wool']
modVersion.names['wool'].should.equal 'Wool'
describe '_parseRecipe', ->
it 'requires output to be defined', ->
parser._errorLocation = 'boat'
test = -> parser._parseRecipe {input:'wool'}
expect(test).to.throw Error, 'boat is missing output'
it 'requires input to be defined', ->
test = -> parser._parseRecipe {output:'wool'}
expect(test).to.throw Error, 'recipe for wool is missing input'
it 'can parse a regular recipe', ->
data =
output: 'bed'
input: [[3, 'planks'], [3, 'wool']]
tools: 'crafting table'
recipe = parser._parseRecipe data
(stack.itemSlug for stack in recipe.output).should.eql ['bed']
(stack.itemSlug for stack in recipe.input).sort().should.eql ['planks', 'wool']
(stack.itemSlug for stack in recipe.tools).should.eql ['crafting_table']
it 'can parse a recipe without tools', ->
recipe = parser._parseRecipe {output:'sugar', input:'sugar cane'}
(stack.itemSlug for stack in recipe.output).should.eql ['sugar']
(stack.itemSlug for stack in recipe.input).sort().should.eql ['sugar_cane']
(stack.itemSlug for stack in recipe.tools).should.eql []
it 'registers all names', ->
data =
output: 'Bed'
input: [[3, 'Oak Wood Planks'], [3, 'Wool']]
tools: 'Crafting Table'
parser._parseRecipe data
_.keys(modVersion.names).sort().should.eql ['bed', 'crafting_table', 'oak_wood_planks', 'wool']
describe '_parseStack', ->
it 'requires the array to have at least one element', ->
parser._errorLocation = 'boat'
options = index:1, field:'output'
expect(-> parser._parseStack([], options)).to.throw Error,
"output element 1 for boat must have at least one element"
it 'can fill in a missing number', ->
stack = parser._parseStack 'boat'
stack.itemSlug.should.equal 'boat'
stack.quantity.should.equal 1
stack2 = parser._parseStack ['boat']
stack2.itemSlug.should.equal 'boat'
stack2.quantity.should.equal 1
it 'requires the data to start with a number', ->
parser._errorLocation = 'boat'
options = index:1, field:'output'
expect(-> parser._parseStack(['2', 'wool'], options)).to.throw Error,
"output element 1 for boat must start with a number"
it 'can parse a basic item', ->
stack = parser._parseStack [2, 'wool']
stack.constructor.name.should.equal 'Stack'
describe '_parseStackList', ->
it 'can promote a single item to a list', ->
list = parser._parseStackList 'boat'
(stack.itemSlug for stack in list).should.eql ['boat']
it 'can require a list to be non-empty', ->
parser._errorLocation = 'boat'
options = field:'output', canBeEmpty:false
expect(-> parser._parseStackList [], options).to.throw Error, 'output for boat cannot be empty'
it 'can allow an empty list', ->
list = parser._parseStackList [], canBeEmpty:true
list.length.should.equal 0
it 'can parse a non-empty list', ->
list = parser._parseStackList [[3, 'plank'], [3, 'wool']]
(stack.itemSlug for stack in list).sort().should.eql ['plank', 'wool']
+2 -1
View File
@@ -31,7 +31,8 @@ require './inventory.test'
require './inventory_parser.test'
require './mod_pack.test'
require './mod_version.test'
require './mod_version_parser.test'
require './mod_version_parsers/v1.test'
mocha.checkLeaks()
mocha.globals ['LiveReload']
mocha.run()