Make Recipe a child of ModVersion, not Item

This commit is contained in:
Andrew Miner
2015-02-15 19:01:16 -08:00
parent a3be372e17
commit 8804605d99
10 changed files with 146 additions and 163 deletions
+6 -4
View File
@@ -90,7 +90,7 @@ module.exports = class CraftingPlan extends BaseModel
return "#{@constructor.name} { return "#{@constructor.name} {
have:#{@have}, have:#{@have},
want:#{@want}, want:#{@want},
need:#{@_need}, need:#{@need},
result:#{@result}, result:#{@result},
steps:#{@steps} steps:#{@steps}
}" }"
@@ -98,11 +98,13 @@ module.exports = class CraftingPlan extends BaseModel
# Private Methods ############################################################################## # Private Methods ##############################################################################
_addStep: (recipe)-> _addStep: (recipe)->
logger.verbose -> "adding step: #{recipe.item.qualifiedSlug}" logger.verbose -> "adding step: #{recipe.slug}"
@steps[recipe.item.qualifiedSlug] = recipe:recipe @steps[recipe.slug] = recipe:recipe
_chooseRecipe: (item)-> _chooseRecipe: (item)->
return item.getPrimaryRecipe() recipes = @modPack.findRecipes item.qualifiedSlug
return null unless recipes?
return recipes[0]
_findSteps: (slug)-> _findSteps: (slug)->
item = @modPack.findItem slug item = @modPack.findItem slug
+19 -34
View File
@@ -9,6 +9,7 @@ BaseCollection = require './base_collection'
BaseModel = require './base_model' BaseModel = require './base_model'
{Event} = require '../constants' {Event} = require '../constants'
Recipe = require './recipe' Recipe = require './recipe'
StringBuilder = require './string_builder'
######################################################################################################################## ########################################################################################################################
@@ -27,27 +28,14 @@ module.exports = class Item extends BaseModel
options.logEvents ?= false options.logEvents ?= false
super attributes, options super attributes, options
@_recipes = []
Object.defineProperties this, Object.defineProperties this,
isCraftable: { get:-> @_recipes.length > 0 } isCraftable: {get:@getIsCraftable}
qualifiedSlug: { get:@getQualifiedSlug } qualifiedSlug: {get:@getQualifiedSlug}
primaryRecipe: { get:@getPrimaryRecipe }
@on Event.change + ':modVersion', => @_qualifiedSlug = null @on Event.change + ':modVersion', => @_qualifiedSlug = null
# Public Methods ############################################################################### # Public Methods ###############################################################################
addRecipe: (recipe)->
[modSlug, itemSlug] = _.decomposeSlug recipe.slug
if itemSlug isnt @slug then throw new Error "cannot add a recipe for #{recipe.slug} to #{@slug}"
recipe.item = this
@_recipes.push recipe
eachRecipe: (callback)->
for recipe in @_recipes
callback recipe
compareTo: (that)-> compareTo: (that)->
if this.slug isnt that.slug if this.slug isnt that.slug
return if this.slug < that.slug then -1 else +1 return if this.slug < that.slug then -1 else +1
@@ -57,6 +45,10 @@ module.exports = class Item extends BaseModel
# Property Methods ############################################################################# # Property Methods #############################################################################
getIsCraftable: ->
return false unless @modVersion?
return @modVersion.hasRecipes @qualifiedSlug
getQualifiedSlug: -> getQualifiedSlug: ->
return @slug if not @modVersion? return @slug if not @modVersion?
@@ -65,25 +57,18 @@ module.exports = class Item extends BaseModel
return @_qualifiedSlug return @_qualifiedSlug
getPrimaryRecipe: ->
return @_recipes[0]
# Object Overrides ############################################################################# # Object Overrides #############################################################################
toString: -> toString: ->
result = [] builder = new StringBuilder
result.push @constructor.name return builder
result.push ' ('; result.push @cid; result.push ') { ' .push @constructor.name, ' (', @cid, ') { '
result.push 'name:"'; result.push @name; result.push '", ' .push 'name:"', @name, '", '
result.push 'isGatherable:'; result.push @isGatherable .push 'isCraftable:', @isCraftable, ', '
.push 'isGatherable:', @isGatherable, ', '
if _.slugify(@name) isnt @slug .onlyIf (@group isnt Item.Group.Other), (b)=>
result.push ', slug:'; result.push @slug b.push 'group:"', @group, '", '
.onlyIf (_.slugify(@name) isnt @slug), (b)=>
if @_recipes.length > 0 b.push 'slug:"', @slug, '", '
result.push ', recipes:«' .push '}'
result.push @_recipes.length .toString()
result.push ' items»'
result.push '}'
return result.join ''
+2 -1
View File
@@ -91,7 +91,8 @@ module.exports = class ModPack extends BaseModel
for mod in @_mods for mod in @_mods
continue unless mod.enabled continue unless mod.enabled
mod.findRecipes slug, result mod.findRecipes slug, result
return result
return if result.length > 0 then result else null
isGatherable: (slug)-> isGatherable: (slug)->
item = @findItem slug item = @findItem slug
+72 -46
View File
@@ -22,30 +22,14 @@ module.exports = class ModVersion extends BaseModel
attributes.mod ?= null attributes.mod ?= null
super attributes, options super attributes, options
@_groups = {} @_groups = {}
@_items = {} @_items = {}
@_names = {} @_names = {}
@_slugs = [] @_recipes = {}
@_slugs = []
# Public Methods ############################################################################### # Public Methods ###############################################################################
addItem: (item)->
if @_items[item.slug]? then throw new Error "duplicate item for #{item.name}"
@_items[item.slug] = item
@_groups[item.group] ?= {}
@_groups[item.group][item.slug] = item
item.modVersion = this
@registerSlug item.slug, item.name
return this
allItemsInGroup: (group)->
result = []
@eachItemInGroup group, (item)-> result.push item
return null if result.length is 0
return result
compareTo: (that)-> compareTo: (that)->
if this.mod? and that.mod? if this.mod? and that.mod?
return this.mod.compareTo that.mod return this.mod.compareTo that.mod
@@ -55,16 +39,24 @@ module.exports = class ModVersion extends BaseModel
return 0 return 0
eachGroup: (callback)-> # Item Methods #################################################################################
groupNames = _.keys @_groups
groupNames.sort (a, b)->
if a is b then return 0
if a is Item.Group.Other then return -1
if b is Item.Group.Other then return +1
return if a < b then -1 else +1
for groupName in groupNames addItem: (item)->
callback groupName if @_items[item.slug]? then throw new Error "duplicate item for #{item.name}"
@_items[item.slug] = item
@_groups[item.group] ?= {}
@_groups[item.group][item.slug] = item
item.modVersion = this
@registerName item.slug, item.name
return this
allItemsInGroup: (group)->
result = []
@eachItemInGroup group, (item)-> result.push item
return null if result.length is 0
return result
eachItem: (callback)-> eachItem: (callback)->
for slug in @_slugs for slug in @_slugs
@@ -80,30 +72,38 @@ module.exports = class ModVersion extends BaseModel
for slug in _.keys(group).sort() for slug in _.keys(group).sort()
callback group[slug] callback group[slug]
findItem: (itemSlug)->
return @_items[itemSlug]
findItemByName: (name)->
for itemSlug, item of @_items
return item if item.name is name
return null
# Group Methods ################################################################################
eachGroup: (callback)->
groupNames = _.keys @_groups
groupNames.sort (a, b)->
if a is b then return 0
if a is Item.Group.Other then return -1
if b is Item.Group.Other then return +1
return if a < b then -1 else +1
for groupName in groupNames
callback groupName
# Name Methods #################################################################################
eachName: (callback)-> eachName: (callback)->
for slug in @_slugs for slug in @_slugs
callback @_names[slug], slug callback @_names[slug], slug
return this return this
findItem: (slug)->
return @_items[slug]
findItemByName: (name)->
return @findItem _.slugify name
findName: (slug)-> findName: (slug)->
return @_names[slug] return @_names[slug]
findRecipes: (itemSlug, result=[])-> registerName: (slug, name)->
for slug in @_slugs
item = @_items[slug]
continue unless item?
item.eachRecipe (recipe)->
result.push recipe if recipe.doesProduce itemSlug
return result
registerSlug: (slug, name)->
hasSlug = @_names[slug]? hasSlug = @_names[slug]?
@_names[slug] = name @_names[slug] = name
@@ -114,6 +114,32 @@ module.exports = class ModVersion extends BaseModel
return this return this
# Recipe Methods ###############################################################################
addRecipe: (recipe)->
recipe.modVersion = this
for stack in recipe.output
recipeList = @_recipes[stack.slug]
if not recipeList?
@_recipes[stack.slug] = recipeList = []
recipeList.push recipe
return this
findRecipes: (itemSlug, result=[])->
recipeList = @_recipes[itemSlug]
if recipeList?
for recipe in recipeList
result.push recipe
return result
hasRecipes: (itemSlug)->
recipeList = @_recipes[itemSlug]
return true if recipeList? and recipeList.length > 0
return false
# Backbone.Model Overrides ##################################################################### # Backbone.Model Overrides #####################################################################
parse: (text)-> parse: (text)->
@@ -135,7 +135,7 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
if not recipeData.input? then throw new Error 'the "input" declaration is required' if not recipeData.input? then throw new Error 'the "input" declaration is required'
if not recipeData.pattern? then throw new Error 'the "pattern" declaration is required' if not recipeData.pattern? then throw new Error 'the "pattern" declaration is required'
localizeSlug = (name, slug)=> qualifySlug = (name, slug)=>
if @_rawData.items[name]? if @_rawData.items[name]?
return _.composeSlugs modVersion.modSlug, slug return _.composeSlugs modVersion.modSlug, slug
else else
@@ -148,8 +148,8 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
inputStacks = [] inputStacks = []
for name in recipeData.input for name in recipeData.input
slug = _.slugify name slug = _.slugify name
modVersion.registerSlug slug, name modVersion.registerName slug, name
slug = localizeSlug name, slug slug = qualifySlug name, slug
inputStacks.push new Stack slug:slug, quantity:0 inputStacks.push new Stack slug:slug, quantity:0
for c in recipeData.pattern for c in recipeData.pattern
@@ -168,26 +168,25 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
outputStacks = [ new Stack slug:item.qualifiedSlug, quantity:recipeData.quantity ] outputStacks = [ new Stack slug:item.qualifiedSlug, quantity:recipeData.quantity ]
for extraData in recipeData.extras for extraData in recipeData.extras
slug = _.slugify extraData.name slug = _.slugify extraData.name
modVersion.registerSlug slug, extraData.name modVersion.registerName slug, extraData.name
slug = localizeSlug extraData.name, slug slug = qualifySlug extraData.name, slug
outputStacks.push new Stack slug:slug, quantity:extraData.quantity outputStacks.push new Stack slug:slug, quantity:extraData.quantity
toolStacks = [] toolStacks = []
for name in recipeData.tools for name in recipeData.tools
slug = _.slugify name slug = _.slugify name
modVersion.registerSlug slug, name modVersion.registerName slug, name
slug = localizeSlug name, slug slug = qualifySlug name, slug
toolStacks.push new Stack slug:slug, quantity:1 toolStacks.push new Stack slug:slug, quantity:1
attributes = attributes =
input: inputStacks input: inputStacks
name: item.name output: outputStacks
pattern: recipeData.pattern pattern: recipeData.pattern
output: outputStacks tools: toolStacks
tools: toolStacks
recipe = new Recipe attributes recipe = new Recipe attributes
item.addRecipe recipe modVersion.addRecipe recipe
return recipe return recipe
# Un-parsing Methods ########################################################################### # Un-parsing Methods ###########################################################################
+13 -24
View File
@@ -13,23 +13,23 @@ Stack = require './stack'
module.exports = class Recipe extends BaseModel module.exports = class Recipe extends BaseModel
constructor: (attributes={}, options={})-> constructor: (attributes={}, options={})->
if attributes.item?
attributes.name = attributes.item.name
attributes.output ?= [new Stack slug:attributes.item.qualifiedSlug, quantity:1]
if not attributes.name? then throw new Error 'attributes.name is required'
if not attributes.input? then throw new Error 'attributes.input is required' if not attributes.input? then throw new Error 'attributes.input is required'
if not attributes.pattern? then throw new Error 'attributes.pattern is required' if not attributes.pattern? then throw new Error 'attributes.pattern is required'
attributes.item ?= null if attributes.slug? and not attributes.output?
attributes.output ?= [new Stack slug:_.slugify(attributes.name), quantity:1] attributes.output = [new Stack slug:attributes.slug, quantity:1]
attributes.pattern = @_parsePattern attributes.pattern else if attributes.output? and not attributes.slug?
attributes.tools ?= [] if attributes.output.length is 0 then throw new Error 'attributes.output cannot be empty'
options.logEvents ?= false attributes.slug = attributes.output[0].slug
super attributes, options else
throw new Error 'attributes.slug or attributes.output is required'
Object.defineProperties this, attributes.pattern = @_parsePattern attributes.pattern
slug: {get:@getSlug}
attributes.modVersion ?= null
attributes.tools ?= []
options.logEvents ?= false
super attributes, options
# Public Methods ############################################################################### # Public Methods ###############################################################################
@@ -44,17 +44,6 @@ module.exports = class Recipe extends BaseModel
return stack.slug return stack.slug
doesProduce: (itemSlug)->
for stack in @output
return true if stack.slug is itemSlug
return false
# Property Methods #############################################################################
getSlug: ->
return @item.qualifiedSlug if @item?
return @output[0].slug
# Object Overrides ############################################################################# # Object Overrides #############################################################################
toString: -> toString: ->
+1
View File
@@ -43,6 +43,7 @@ describe 'crafting_plan.coffee', ->
it 'can craft a single step recipe', -> it 'can craft a single step recipe', ->
plan.want.add 'oak_plank' plan.want.add 'oak_plank'
plan.craft() plan.craft()
logger.debug "plan: #{plan}"
plan.need.toList().should.eql ['oak_log'] plan.need.toList().should.eql ['oak_log']
plan.result.toList().should.eql [[4, 'minecraft__oak_plank']] plan.result.toList().should.eql [[4, 'minecraft__oak_plank']]
+1 -1
View File
@@ -23,7 +23,7 @@ describe 'mod_pack.coffee', ->
minecraft.addModVersion new ModVersion modSlug:minecraft.slug, version:'1.7.10' minecraft.addModVersion new ModVersion modSlug:minecraft.slug, version:'1.7.10'
minecraft.activeModVersion.addItem new Item name:'Wool' minecraft.activeModVersion.addItem new Item name:'Wool'
minecraft.activeModVersion.addItem new Item name:'Bed', recipes:[''] minecraft.activeModVersion.addItem new Item name:'Bed', recipes:['']
minecraft.activeModVersion.registerSlug 'iron_chestplate', 'Iron Chestplate' minecraft.activeModVersion.registerName 'iron_chestplate', 'Iron Chestplate'
buildcraft = new Mod slug:'buildcraft', name:'Buildcraft' buildcraft = new Mod slug:'buildcraft', name:'Buildcraft'
buildcraft.addModVersion new ModVersion modSlug:buildcraft.slug, version:'6.2.6' buildcraft.addModVersion new ModVersion modSlug:buildcraft.slug, version:'6.2.6'
@@ -27,7 +27,8 @@ describe 'mod_version_parser_v1.coffee', ->
recipe:; input:Alpha; pattern:... .0. ...; recipe:; input:Alpha; pattern:... .0. ...;
recipe:; input:Bravo; pattern:... 0.0 ...;" recipe:; input:Bravo; pattern:... 0.0 ...;"
modVersion = parser.parse recipes modVersion = parser.parse recipes
recipes = modVersion._items.charlie._recipes recipes = modVersion.findRecipes 'test__charlie'
logger.debug "recipes: #{util.inspect(recipes)}"
recipes[0].input[0].slug.should.equal 'alpha' recipes[0].input[0].slug.should.equal 'alpha'
recipes[1].input[0].slug.should.equal 'bravo' recipes[1].input[0].slug.should.equal 'bravo'
@@ -67,7 +68,7 @@ describe 'mod_version_parser_v1.coffee', ->
it 'adds "input" when present', -> it 'adds "input" when present', ->
modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo, Charlie; pattern: ... 012 ...' modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo, Charlie; pattern: ... 012 ...'
slugs = (s.slug for s in modVersion._items.charlie._recipes[0].input) slugs = (s.slug for s in modVersion.findRecipes('test__charlie')[0].input)
slugs.should.eql ['alpha', 'bravo', 'test__charlie'] slugs.should.eql ['alpha', 'bravo', 'test__charlie']
it 'requires an "input" declaration', -> it 'requires an "input" declaration', ->
@@ -90,7 +91,7 @@ describe 'mod_version_parser_v1.coffee', ->
it 'adds "pattern" when present', -> it 'adds "pattern" when present', ->
modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo; pattern:... .0. .1.' modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo; pattern:... .0. .1.'
modVersion._items.charlie._recipes[0].pattern.should.equal '... .0. .1.' modVersion.findRecipes('test__charlie')[0].pattern.should.equal '... .0. .1.'
it 'requires a "pattern" declaration', -> it 'requires a "pattern" declaration', ->
func = -> parser.parse baseText + 'recipe:; input:Alpha, Bravo' func = -> parser.parse baseText + 'recipe:; input:Alpha, Bravo'
@@ -118,7 +119,7 @@ describe 'mod_version_parser_v1.coffee', ->
it 'computes the input stack sizes from the pattern', -> it 'computes the input stack sizes from the pattern', ->
modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo, Charlie; pattern:111 .0. 2.2' modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo, Charlie; pattern:111 .0. 2.2'
recipe = modVersion._items.charlie._recipes[0] recipe = modVersion.findRecipes('test__charlie')[0]
recipe.input[0].quantity.should.equal 1 recipe.input[0].quantity.should.equal 1
recipe.input[1].quantity.should.equal 3 recipe.input[1].quantity.should.equal 3
recipe.input[2].quantity.should.equal 2 recipe.input[2].quantity.should.equal 2
@@ -134,7 +135,7 @@ describe 'mod_version_parser_v1.coffee', ->
it 'adds "quantity" when present', -> it 'adds "quantity" when present', ->
modVersion = parser.parse baseText + 'quantity: 2' modVersion = parser.parse baseText + 'quantity: 2'
modVersion._items.charlie._recipes[0].output[0].quantity.should.equal 2 modVersion.findRecipes('test__charlie')[0].output[0].quantity.should.equal 2
it 'does not allow a duplicate "quantity" declaration', -> it 'does not allow a duplicate "quantity" declaration', ->
func = -> parser.parse baseText + 'quantity:1; quantity:2' func = -> parser.parse baseText + 'quantity:1; quantity:2'
@@ -146,7 +147,7 @@ describe 'mod_version_parser_v1.coffee', ->
it 'assumes a quantity of 1 by default', -> it 'assumes a quantity of 1 by default', ->
modVersion = parser.parse baseText modVersion = parser.parse baseText
modVersion._items.charlie._recipes[0].output[0].quantity.should.equal 1 modVersion.findRecipes('test__charlie')[0].output[0].quantity.should.equal 1
it 'does not allow "quantity" before recipe', -> it 'does not allow "quantity" before recipe', ->
func = -> parser.parse 'item:Bravo; quantity:12; recipe:;' func = -> parser.parse 'item:Bravo; quantity:12; recipe:;'
@@ -159,13 +160,13 @@ describe 'mod_version_parser_v1.coffee', ->
it 'adds a single item as the default output', -> it 'adds a single item as the default output', ->
modVersion = parser.parse baseText modVersion = parser.parse baseText
stack = modVersion._items.bravo._recipes[0].output[0] stack = modVersion.findRecipes('test__bravo')[0].output[0]
stack.slug.should.equal 'test__bravo' stack.slug.should.equal 'test__bravo'
stack.quantity.should.equal 1 stack.quantity.should.equal 1
it 'can add multiple extras with quantities', -> it 'can add multiple extras with quantities', ->
modVersion = parser.parse baseText + 'extras:2 Delta, 4 Echo' modVersion = parser.parse baseText + 'extras:2 Delta, 4 Echo'
output = modVersion._items.bravo._recipes[0].output output = modVersion.findRecipes('test__bravo')[0].output
output[0].slug.should.equal 'test__bravo' output[0].slug.should.equal 'test__bravo'
output[0].quantity.should.equal 1 output[0].quantity.should.equal 1
output[1].slug.should.equal 'test__delta' output[1].slug.should.equal 'test__delta'
@@ -192,11 +193,11 @@ describe 'mod_version_parser_v1.coffee', ->
it 'can add a single tool', -> it 'can add a single tool', ->
modVersion = parser.parse baseText + 'tools: Furnace' modVersion = parser.parse baseText + 'tools: Furnace'
modVersion._items.bravo._recipes[0].tools[0].slug.should.equal 'furnace' modVersion.findRecipes('test__bravo')[0].tools[0].slug.should.equal 'furnace'
it 'can add multiple tools', -> it 'can add multiple tools', ->
modVersion = parser.parse baseText + 'tools: Crafting Table, Furnace' modVersion = parser.parse baseText + 'tools: Crafting Table, Furnace'
tools = modVersion._items.bravo._recipes[0].tools tools = modVersion.findRecipes('test__bravo')[0].tools
tools[0].slug.should.equal 'crafting_table' tools[0].slug.should.equal 'crafting_table'
tools[1].slug.should.equal 'furnace' tools[1].slug.should.equal 'furnace'
+9 -30
View File
@@ -23,36 +23,31 @@ describe 'recipe.coffee', ->
input = [ new Stack(slug:'iron_gear'), new Stack(slug:'gold_ingot', quantity:4) ] input = [ new Stack(slug:'iron_gear'), new Stack(slug:'gold_ingot', quantity:4) ]
pattern = '.1. 101 .1.' pattern = '.1. 101 .1.'
it 'requires a name', ->
expect(-> new Recipe input:input, pattern:pattern).to.throw Error, 'attributes.name is required'
it 'requires input', -> it 'requires input', ->
expect(-> new Recipe name:'Gold Gear', pattern:pattern).to.throw Error, 'attributes.input is required' expect(-> new Recipe slug:'gold_gear', pattern:pattern).to.throw Error, 'attributes.input is required'
it 'requires a pattern', -> it 'requires a pattern', ->
expect(-> new Recipe name:'Gold Gear', input:input).to.throw Error, 'attributes.pattern is required' expect(-> new Recipe slug:'gold_gear', input:input).to.throw Error, 'attributes.pattern is required'
it 'allows an item to provide required attributes', -> it 'requires either outputs or a slug', ->
item = new Item name:'Gold Gear' f = -> new Recipe input:input, pattern:pattern
recipe = new Recipe item:item, input:input, pattern:pattern expect(f).to.throw 'attributes.slug or attributes.output is required'
recipe.name.should.equal 'Gold Gear'
(o.slug for o in recipe.output).should.eql ['gold_gear']
it 'creates default output', -> it 'creates default output', ->
recipe = new Recipe name:'Gold Gear', input:input, pattern:pattern recipe = new Recipe slug:'gold_gear', input:input, pattern:pattern
recipe.output.length.should.equal 1 recipe.output.length.should.equal 1
recipe.output[0].slug.should.equal 'gold_gear' recipe.output[0].slug.should.equal 'gold_gear'
recipe.output[0].quantity.should.equal 1 recipe.output[0].quantity.should.equal 1
it 'assigns a default slug', -> it 'assigns a default slug', ->
recipe = new Recipe name:'Gold Gear', input:input, pattern:pattern recipe = new Recipe input:input, pattern:pattern, output:[new Stack slug:'gold_gear']
recipe.slug.should.equal 'gold_gear' recipe.slug.should.equal 'gold_gear'
describe 'getItemSlugAt', -> describe 'getItemSlugAt', ->
beforeEach -> beforeEach ->
input = [ new Stack(slug:'iron_gear'), new Stack(slug:'gold_ingot', quantity:4) ] input = [ new Stack(slug:'iron_gear'), new Stack(slug:'gold_ingot', quantity:4) ]
recipe = new Recipe name:'Gold Gear', input:input, pattern:'.1. 101 .1.' recipe = new Recipe slug:'gold_gear', input:input, pattern:'.1. 101 .1.'
it 'returns the proper item for an early slot', -> it 'returns the proper item for an early slot', ->
recipe.getItemSlugAt(1).should.equal 'gold_ingot' recipe.getItemSlugAt(1).should.equal 'gold_ingot'
@@ -63,26 +58,10 @@ describe 'recipe.coffee', ->
it 'returns null for an invalid slot', -> it 'returns null for an invalid slot', ->
expect(recipe.getItemSlugAt(12)).to.be.null expect(recipe.getItemSlugAt(12)).to.be.null
describe 'doesProduce', ->
beforeEach ->
input = [ new Stack(slug:'empty_cell'), new Stack(slug:'water_bucket') ]
output = [ new Stack(slug:'water_cell'), new Stack(slug:'bucket') ]
recipe = new Recipe name:'Water Cell', input:input, output:output, pattern:'... .0. .1.'
it 'returns true when asked for the primary output', ->
recipe.doesProduce('water_cell').should.be.true
it 'returns true when asked for a secondary output', ->
recipe.doesProduce('bucket').should.be.true
it 'return false when asked for a non-output', ->
recipe.doesProduce('cake').should.be.false
describe '_parsePattern', -> describe '_parsePattern', ->
beforeEach -> beforeEach ->
recipe = new Recipe name:'Oak Wood Planks', input:[new Stack slug:'oak_wood'], pattern:'... .0. ...' recipe = new Recipe slug:'oak_wood_planks', input:[new Stack slug:'oak_wood'], pattern:'... .0. ...'
it 'normalizes invalid characters', -> it 'normalizes invalid characters', ->
recipe._parsePattern('$$0 #() 010').should.equal '..0 ... 010' recipe._parsePattern('$$0 #() 010').should.equal '..0 ... 010'