Convert codebase to using ItemSlug

* Flesh out the formerly incomplete ItemSlug class
* Convert all uses of text item slugs to use ItemSlug
* Move the ItemSlug class under models where it properly belongs
* Avoid the use of `slug` as a local variable or item attribute
  wherever possible to avoid confusion between various kinds of slugs
* Merge the InventoryParser class into the Inventory class as it is
  unlikely to need to support multiple versions
* Simplify the ModPack/Mod/ModVersion interfaces by replacing the use
  of various "helper" methods with equivalent use of more generic
  methods
* Update the various methods of ModPack/Mod/ModVersion to be able to
  work with qualified or unqualified ItemSlugs
* Remove the unused BaseCollection class
* Add tests for ItemSlug and update all other tests to reflect
  all the other changes
This commit is contained in:
Andrew Miner
2015-02-18 10:30:53 -08:00
parent 100ce1bc70
commit e88821d449
33 changed files with 624 additions and 535 deletions
+20 -30
View File
@@ -6,6 +6,7 @@ All rights reserved.
###
CraftingPlan = require '../src/scripts/models/crafting_plan'
ItemSlug = require '../src/scripts/models/item_slug'
Mod = require '../src/scripts/models/mod'
ModPack = require '../src/scripts/models/mod_pack'
ModVersion = require '../src/scripts/models/mod_version'
@@ -41,54 +42,43 @@ describe 'crafting_plan.coffee', ->
describe 'under the simplest conditions', ->
it 'can craft a single step recipe', ->
plan.want.add 'oak_plank'
plan.want.add ItemSlug.slugify 'oak_plank'
plan.craft()
plan.need.toList().should.eql ['oak_log']
plan.result.toList().should.eql [[4, 'minecraft__oak_plank']]
plan.need.unparse().should.equal 'oak_log'
plan.result.unparse().should.equal '4.minecraft__oak_plank'
it 'can craft a multi-step recipe', ->
plan.want.add 'crafting_table'
plan.want.add ItemSlug.slugify 'crafting_table'
plan.craft()
plan.need.toList().should.eql ['oak_log']
plan.result.toList().should.eql ['minecraft__crafting_table']
plan.need.unparse().should.equal 'oak_log'
plan.result.unparse().should.equal 'minecraft__crafting_table'
it 'can craft a multi-step recipe using tools', ->
plan.want.add 'furnace'
plan.want.add ItemSlug.slugify 'furnace'
plan.craft()
plan.need.toList().should.eql [[8, 'cobblestone']]
plan.result.toList().should.eql ['minecraft__furnace']
plan.need.unparse().should.equal '8.cobblestone'
plan.result.unparse().should.equal 'minecraft__furnace'
it 'can craft a multi-step recipe re-using tools', ->
plan.want.add 'iron_sword'
plan.want.add ItemSlug.slugify 'iron_sword'
plan.craft()
plan.need.toList().should.eql [[2, 'furnace_fuel'], [2, 'iron_ore'], 'oak_log']
plan.result.toList().should.eql [
'minecraft__iron_sword',
[2, 'minecraft__oak_plank'],
[3, 'minecraft__stick']
]
plan.need.unparse().should.equal '2.furnace_fuel:2.iron_ore:oak_log'
plan.result.unparse().should.equal 'minecraft__iron_sword:2.minecraft__oak_plank:3.minecraft__stick'
describe 'with building tools', ->
it 'can craft a multi-step recipe using tools', ->
plan.includingTools = true
plan.want.add 'furnace'
plan.want.add ItemSlug.slugify 'furnace'
plan.craft()
plan.need.toList().should.eql [[8, 'cobblestone'], 'oak_log']
plan.result.toList().should.eql ['minecraft__crafting_table', 'minecraft__furnace']
plan.need.unparse().should.equal '8.cobblestone:oak_log'
plan.result.unparse().should.equal 'minecraft__crafting_table:minecraft__furnace'
it 'can craft a multi-step recipe re-using tools', ->
plan.includingTools = true
plan.want.add 'iron_sword'
plan.want.add ItemSlug.slugify 'iron_sword'
plan.craft()
plan.need.toList().should.eql [
[8, 'cobblestone'], [2, 'furnace_fuel'], [2, 'iron_ore'], [2, 'oak_log']
]
plan.result.toList().should.eql [
'minecraft__crafting_table',
'minecraft__furnace',
'minecraft__iron_sword',
[2, 'minecraft__oak_plank'],
[3, 'minecraft__stick']
]
plan.need.unparse().should.eql '8.cobblestone:2.furnace_fuel:2.iron_ore:2.oak_log'
plan.result.unparse().should.equal 'minecraft__crafting_table:minecraft__furnace:' +
'minecraft__iron_sword:2.minecraft__oak_plank:3.minecraft__stick'
+71 -42
View File
@@ -9,6 +9,7 @@
EventRecorder = require './event_recorder'
Inventory = require '../src/scripts/models/inventory'
Item = require '../src/scripts/models/item'
ItemSlug = require '../src/scripts/models/item_slug'
########################################################################################################################
@@ -20,30 +21,30 @@ describe 'inventory.coffee', ->
beforeEach ->
inventory = new Inventory {}, silent:false
inventory.add 'wool', 4
inventory.add 'string', 20
inventory.add 'boat'
inventory.add ItemSlug.slugify('wool'), 4
inventory.add ItemSlug.slugify('string'), 20
inventory.add ItemSlug.slugify('boat')
describe 'add', ->
it 'can add to an empty inventory', ->
inventory.add 'iron_ingot', 4
inventory.add ItemSlug.slugify('iron_ingot'), 4
stack = inventory._stacks['iron_ingot']
stack.constructor.name.should.equal 'Stack'
stack.slug.should.equal 'iron_ingot'
stack.itemSlug.qualified.should.equal 'iron_ingot'
stack.quantity.should.equal 4
it 'can augment quantity of existing items', ->
inventory.add 'wool', 2
inventory.toList().should.eql ['boat', [20, 'string'], [6, 'wool']]
inventory.add ItemSlug.slugify('wool'), 2
inventory.unparse().should.equal 'boat:20.string:6.wool'
it 'can add zero quantity', ->
inventory.add 'wool', 0
inventory.toList().should.eql ['boat', [20, 'string'], [4, 'wool']]
inventory.add ItemSlug.slugify('wool'), 0
inventory.unparse().should.equal 'boat:20.string:4.wool'
it 'emits the proper events', ->
events = new EventRecorder inventory
inventory.add 'iron_ingot', 10
inventory.add ItemSlug.slugify('iron_ingot'), 10
events.names.should.eql [Event.add, Event.change]
describe 'addInventory', ->
@@ -51,24 +52,24 @@ describe 'inventory.coffee', ->
it 'can add to an empty inventory', ->
newInventory = new Inventory
newInventory.addInventory inventory
newInventory._slugs.should.eql ['boat', 'string', 'wool']
newInventory.unparse().should.equal 'boat:20.string:4.wool'
it 'can add a mix of new and existing items', ->
newInventory = new Inventory
newInventory.add 'string', 2
newInventory.add ItemSlug.slugify('string'), 2
newInventory.addInventory inventory
newInventory.toList().should.eql ['boat', [22, 'string'], [4, 'wool']]
newInventory.unparse().should.equal 'boat:22.string:4.wool'
describe 'clone', ->
it 'creates an empty inventory from an empty inventory', ->
a = new Inventory
b = a.clone()
b._slugs.should.eql []
b._itemSlugs.should.eql []
it 'faithfully copies an existing inventory', ->
copy = inventory.clone()
copy.toList().should.eql ['boat', [20, 'string'], [4, 'wool']]
copy.unparse().should.equal 'boat:20.string:4.wool'
describe 'each', ->
@@ -80,16 +81,16 @@ describe 'inventory.coffee', ->
it 'works when items have only been added', ->
result = []
inventory.each (stack)-> result.push stack.slug
inventory.each (stack)-> result.push stack.itemSlug.qualified
result.should.eql ['boat', 'string', 'wool']
it 'works when items have been augmented', ->
inventory.add 'iron_ingot'
inventory.add 'boat'
inventory.add 'wool', 2
inventory.add ItemSlug.slugify 'iron_ingot'
inventory.add ItemSlug.slugify 'boat'
inventory.add ItemSlug.slugify('wool'), 2
result = []
inventory.each (stack)-> result.push stack.slug
inventory.each (stack)-> result.push stack.itemSlug.qualified
result.should.eql ['boat', 'iron_ingot', 'string', 'wool']
describe 'hasAtLeast', ->
@@ -107,39 +108,67 @@ describe 'inventory.coffee', ->
inventory.hasAtLeast('wool', 4).should.be.true
inventory.hasAtLeast('wool', 5).should.be.false
describe 'localizeTo', ->
describe 'localize', ->
before ->
modPack =
map:
wool: 'minecraft__wool'
string: 'minecraft__string'
boat: 'minecraft__boat'
stone_gear: 'buildcraft__stone_gear'
modSlug:
wool: 'minecraft'
string: 'minecraft'
boat: 'minecraft'
stone_gear: 'buildcraft'
findItem: (slug)->
[modSlug, itemSlug] = _.decomposeSlug slug
return slug:itemSlug, qualifiedSlug:@map[itemSlug]
return slug:new ItemSlug @modSlug[slug.item], slug.item
it 'replaces item slugs with qualified slugs', ->
inventory.add 'stone_gear'
inventory.localizeTo modPack
inventory.toList().should.eql [
'minecraft__boat',
[20, 'minecraft__string'],
[4, 'minecraft__wool'],
inventory.add ItemSlug.slugify 'stone_gear'
inventory.modPack = modPack
inventory.localize()
slugs = []
inventory.each (stack)-> slugs.push stack.itemSlug.qualified
slugs.should.eql [
'minecraft__boat'
'minecraft__string'
'minecraft__wool'
'buildcraft__stone_gear'
]
it 'ignores qualified slugs', ->
inventory.add 'buildcraft__stone_gear'
inventory.localizeTo modPack
inventory.toList().should.eql [
'minecraft__boat',
[20, 'minecraft__string'],
[4, 'minecraft__wool'],
inventory.add ItemSlug.slugify 'buildcraft__stone_gear'
inventory.modPack = modPack
inventory.localize()
slugs = []
inventory.each (stack)-> slugs.push stack.itemSlug.qualified
slugs.should.eql [
'minecraft__boat'
'minecraft__string'
'minecraft__wool'
'buildcraft__stone_gear'
]
describe 'parse', ->
beforeEach ->
inventory = new Inventory {}, silent:false
it 'ignores an empty string', ->
result = inventory.parse ''
result.unparse().should.eql ''
it 'can parse a single item without quantity', ->
result = inventory.parse 'wool'
result.unparse().should.equal 'wool'
it 'can parse a single item with quantity', ->
result = inventory.parse '4.wool'
result.unparse().should.equal '4.wool'
it 'can parse multiple mixed-type items', ->
result = inventory.parse '4.wool:10.string:boat'
result.unparse().should.equal 'boat:10.string:4.wool'
describe 'pop', ->
it 'returns null for an empty inventory', ->
@@ -149,9 +178,9 @@ describe 'inventory.coffee', ->
it 'completely removes the last item', ->
stack = inventory.pop()
stack.slug.should.equal 'wool'
stack.itemSlug.qualified.should.equal 'wool'
stack.quantity.should.equal 4
inventory.toList().should.eql ['boat', [20, 'string']]
inventory.unparse().should.equal 'boat:20.string'
it 'triggers the right events', ->
events = new EventRecorder inventory
-42
View File
@@ -1,42 +0,0 @@
###
# Crafting Guide - inventory_parser.test.coffee
#
# Copyright (c) 2014-2015 by Redwood Labs
# All rights reserved.
###
Inventory = require '../src/scripts/models/inventory'
InventoryParser = require '../src/scripts/models/inventory_parser'
Item = require '../src/scripts/models/item'
########################################################################################################################
parser = null
########################################################################################################################
describe 'inventory_parser.coffee', ->
beforeEach -> parser = new InventoryParser
it 'returns an empty Inventory for an empty string', ->
result = parser.parse ''
result.toList().should.eql []
it 'can parse a single item without quantity', ->
result = parser.parse 'wool'
result.toList().should.eql ['wool']
it 'can parse a single item with quantity', ->
result = parser.parse '4.wool'
result.toList().should.eql [[4, 'wool']]
it 'can parse multiple mixed-type items', ->
result = parser.parse '4.wool:10.string:boat'
result.toList().should.eql ['boat', [10, 'string'], [4, 'wool']]
it 're-uses the given inventory object', ->
inventory = new Inventory
inventory.add 'string', 8
result = parser.parse '4.wool', inventory
result.toList().should.eql [[8, 'string'], [4, 'wool']]
+136
View File
@@ -0,0 +1,136 @@
###
Crafting Guide - item_slug.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
ItemSlug = require '../src/scripts/models/item_slug'
########################################################################################################################
describe 'item_slug.coffee', ->
describe 'constructor', ->
it 'can handle one argument', ->
slug = new ItemSlug 'alpha'
slug.item.should.equal 'alpha'
expect(slug.mod).to.be.null
slug.qualified.should.equal 'alpha'
it 'can handle two arguments', ->
slug = new ItemSlug 'alpha', 'bravo'
slug.mod.should.equal 'alpha'
slug.item.should.equal 'bravo'
slug.qualified.should.equal 'alpha__bravo'
it 'throws with zero arguments', ->
f = -> new ItemSlug
expect(f).to.throw Error, 'expected arguments to be "modSlug, itemSlug" or just "itemSlug"'
it 'throws with more arguments', ->
f = -> new ItemSlug 'alpha', 'bravo', 'charlie'
expect(f).to.throw Error, 'expected arguments to be "modSlug, itemSlug" or just "itemSlug"'
describe 'ItemSlug.compare', ->
it 'sorts qualified slugs first', ->
a = new ItemSlug 'alpha'
b = new ItemSlug 'bravo', 'charlie'
ItemSlug.compare(a, b).should.equal +1
ItemSlug.compare(b, a).should.equal -1
it 'sorts by mod when both are qualified', ->
a = new ItemSlug 'alpha', 'bravo'
b = new ItemSlug 'charlie', 'delta'
ItemSlug.compare(a, b).should.equal -1
ItemSlug.compare(b, a).should.equal +1
it 'sorts by item when both are qualified in the same mod', ->
a = new ItemSlug 'alpha', 'bravo'
b = new ItemSlug 'charlie', 'bravo'
ItemSlug.compare(a, b).should.equal -1
ItemSlug.compare(b, a).should.equal +1
it 'sorts by item when not qualified', ->
a = new ItemSlug 'alpha'
b = new ItemSlug 'bravo'
ItemSlug.compare(a, b).should.equal -1
ItemSlug.compare(b, a).should.equal +1
describe 'ItemSlug.equal', ->
it 'requires both to have the same mod', ->
a = new ItemSlug 'alpha', 'bravo'
b = new ItemSlug 'alpha', 'charlie'
c = new ItemSlug 'alpha', 'bravo'
ItemSlug.equal(a, b).should.be.false
ItemSlug.equal(a, c).should.be.true
it 'requires both to have the same item', ->
a = new ItemSlug 'alpha', 'bravo'
b = new ItemSlug 'alpha', 'charlie'
c = new ItemSlug 'alpha', 'bravo'
ItemSlug.equal(a, b).should.be.false
ItemSlug.equal(a, c).should.be.true
describe 'ItemSlug.slugify', ->
it 'can slugify a pure name', ->
slug = ItemSlug.slugify 'Alpha Bravo (Charlie)'
slug.item.should.equal 'alpha_bravo_charlie'
expect(slug.mod).to.be.null
it 'can slugify a simple item slug', ->
slug = ItemSlug.slugify 'alpha_bravo_charlie'
slug.item.should.equal 'alpha_bravo_charlie'
expect(slug.mod).to.be.null
it 'can slugify a fully-qualified slug', ->
slug = ItemSlug.slugify 'alpha_bravo__charlie_delta'
slug.mod.should.equal 'alpha_bravo'
slug.item.should.equal 'charlie_delta'
describe 'matches', ->
it 'ignores mod when either is unqualified', ->
a = new ItemSlug 'alpha', 'bravo'
b = new ItemSlug 'bravo'
c = new ItemSlug 'charlie'
a.matches(b).should.be.true
a.matches(c).should.be.false
it 'observes differences in mod when all are qualified', ->
a = new ItemSlug 'alpha', 'bravo'
b = new ItemSlug 'charlie', 'bravo'
c = new ItemSlug 'delta', 'echo'
d = new ItemSlug 'alpha', 'bravo'
a.matches(b).should.be.false
a.matches(c).should.be.false
a.matches(d).should.be.true
describe 'isQualified', ->
it 'returns true only when the mod slug is set', ->
a = new ItemSlug 'alpha', 'bravo'
b = new ItemSlug 'charlie'
a.isQualified.should.be.true
b.isQualified.should.be.false
describe '[]', ->
it 'allows slugs as a key', ->
slug = new ItemSlug 'alpha', 'bravo'
data = {}
data[slug] = 'foo'
data['alpha__bravo'].should.equal 'foo'
data[slug].should.equal 'foo'
+10 -9
View File
@@ -6,6 +6,7 @@ All rights reserved.
###
Item = require '../src/scripts/models/item'
ItemSlug = require '../src/scripts/models/item_slug'
Mod = require '../src/scripts/models/mod'
ModPack = require '../src/scripts/models/mod_pack'
ModVersion = require '../src/scripts/models/mod_version'
@@ -23,7 +24,7 @@ describe 'mod_pack.coffee', ->
minecraft.addModVersion new ModVersion modSlug:minecraft.slug, version:'1.7.10'
minecraft.activeModVersion.addItem new Item name:'Wool'
minecraft.activeModVersion.addItem new Item name:'Bed', recipes:['']
minecraft.activeModVersion.registerName 'iron_chestplate', 'Iron Chestplate'
minecraft.activeModVersion.registerName ItemSlug.slugify('iron_chestplate'), 'Iron Chestplate'
buildcraft = new Mod slug:'buildcraft', name:'Buildcraft'
buildcraft.addModVersion new ModVersion modSlug:buildcraft.slug, version:'6.2.6'
@@ -46,24 +47,24 @@ describe 'mod_pack.coffee', ->
describe 'findItem', ->
it 'can find an item by partial slug', ->
item = modPack.findItem 'wool'
item.qualifiedSlug.should.equal 'minecraft__wool'
item = modPack.findItem ItemSlug.slugify 'wool'
item.slug.qualified.should.equal 'minecraft__wool'
it 'can find an item by full slug', ->
item = modPack.findItem 'minecraft__wool'
item = modPack.findItem ItemSlug.slugify 'minecraft__wool'
item.name.should.equal 'Wool'
it 'can find an ambiguous item by full slug', ->
buildcraft.activeVersion = Mod.Version.Latest
industrialCraft.activeVersion = Mod.Version.Latest
item = modPack.findItem 'industrial_craft__wrench'
item = modPack.findItem ItemSlug.slugify 'industrial_craft__wrench'
item.name.should.equal 'Wrench'
item.modVersion.mod.name.should.equal 'Industrial Craft'
it 'can find an ambiguous item by partial slug', ->
buildcraft.activeVersion = Mod.Version.Latest
industrialCraft.activeVersion = Mod.Version.Latest
item = modPack.findItem 'wrench'
item = modPack.findItem ItemSlug.slugify 'wrench'
item.name.should.equal 'Wrench'
item.modVersion.mod.name.should.equal 'Buildcraft'
@@ -80,7 +81,7 @@ describe 'mod_pack.coffee', ->
describe 'findItemDisplay', ->
it 'returns all data for a regular Minecraft item', ->
display = modPack.findItemDisplay 'bed'
display = modPack.findItemDisplay ItemSlug.slugify 'bed'
display.iconUrl.should.equal '/data/minecraft/1.7.10/images/bed.png'
display.itemUrl.should.equal '/mod/minecraft/bed'
display.itemName.should.equal 'Bed'
@@ -88,14 +89,14 @@ describe 'mod_pack.coffee', ->
it 'returns all data for an item in an enabled mod', ->
buildcraft.activeVersion = '6.2.6'
display = modPack.findItemDisplay 'stone_gear'
display = modPack.findItemDisplay ItemSlug.slugify 'stone_gear'
display.iconUrl.should.equal '/data/buildcraft/6.2.6/images/stone_gear.png'
display.itemUrl.should.equal '/mod/buildcraft/stone_gear'
display.itemName.should.equal 'Stone Gear'
display.modSlug.should.equal 'buildcraft'
it 'assumes an unfound item is from Minecraft', ->
display = modPack.findItemDisplay 'iron_chestplate'
display = modPack.findItemDisplay ItemSlug.slugify 'iron_chestplate'
display.iconUrl.should.equal '/data/minecraft/1.7.10/images/iron_chestplate.png'
display.itemUrl.should.equal '/mod/minecraft/iron_chestplate'
display.itemName.should.equal 'Iron Chestplate'
+9 -8
View File
@@ -6,6 +6,7 @@ All rights reserved.
###
Item = require '../src/scripts/models/item'
ItemSlug = require '../src/scripts/models/item_slug'
ModVersion = require '../src/scripts/models/mod_version'
########################################################################################################################
@@ -57,24 +58,24 @@ describe 'mod_version.coffee', ->
it 'returns immediately for unknown group', ->
slugs = []
modVersion.eachItemInGroup 'foobar', (item)-> slugs.push item.slug
modVersion.eachItemInGroup 'foobar', (item)-> slugs.push item.slug.qualified
slugs.should.eql []
it 'calls callback for exactly the items in a group in order', ->
slugs = []
modVersion.eachItemInGroup 'letter', (item)-> slugs.push item.slug
slugs.should.eql ['alpha', 'bravo']
modVersion.eachItemInGroup 'letter', (item)-> slugs.push item.slug.qualified
slugs.should.eql ['test__alpha', 'test__bravo']
slugs = []
modVersion.eachItemInGroup 'number', (item)-> slugs.push item.slug
slugs.should.eql ['one', 'two']
modVersion.eachItemInGroup 'number', (item)-> slugs.push item.slug.qualified
slugs.should.eql ['test__one', 'test__two']
describe 'findItemByName', ->
it 'locates items by slugified name', ->
modVersion.addItem new Item name:'Crafting Table'
modVersion.findItemByName('Crafting Table').slug.should.equal 'crafting_table'
modVersion.findItemByName('Crafting Table').slug.qualified.should.equal 'test__crafting_table'
describe 'findRecipes', ->
@@ -91,5 +92,5 @@ describe 'mod_version.coffee', ->
"""
it 'finds all recipes which list item as output', ->
recipes = modVersion.findRecipes 'test__bucket'
(r.output[0].slug for r in recipes).sort().should.eql ['test__bucket', 'test__cake', 'test__cake']
recipes = modVersion.findRecipes ItemSlug.slugify('Bucket')
(r.output[0].itemSlug.item for r in recipes).sort().should.eql ['bucket', 'cake', 'cake']
@@ -6,6 +6,7 @@ All rights reserved.
###
CommandParserVersionBase = require '../../src/scripts/models/parser_versions/command_parser_version_base'
ItemSlug = require '../../src/scripts/models/item_slug'
ModVersion = require '../../src/scripts/models/mod_version'
ModVersionParserV1 = require '../../src/scripts/models/parser_versions/mod_version_parser_v1'
@@ -28,9 +29,9 @@ describe 'mod_version_parser_v1.coffee', ->
recipe:; input:Alpha; pattern:... .0. ...;
recipe:; input:Bravo; pattern:... 0.0 ...;"
modVersion = parser.parse recipes
recipes = modVersion.findRecipes 'test__charlie'
recipes[0].input[0].slug.should.equal 'alpha'
recipes[1].input[0].slug.should.equal 'bravo'
recipes = modVersion.findRecipes ItemSlug.slugify 'charlie'
recipes[0].input[0].itemSlug.qualified.should.equal 'alpha'
recipes[1].input[0].itemSlug.qualified.should.equal 'bravo'
describe 'name', ->
@@ -68,8 +69,8 @@ describe 'mod_version_parser_v1.coffee', ->
it 'adds "input" when present', ->
modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo, Charlie; pattern: ... 012 ...'
slugs = (s.slug for s in modVersion.findRecipes('test__charlie')[0].input)
slugs.should.eql ['alpha', 'bravo', 'test__charlie']
slugs = (s.itemSlug.item for s in modVersion.findRecipes(ItemSlug.slugify('charlie'))[0].input)
slugs.should.eql ['alpha', 'bravo', 'charlie']
it 'requires an "input" declaration', ->
func = -> parser.parse baseText + 'recipe:; pattern: ... .0. ...'
@@ -85,13 +86,13 @@ describe 'mod_version_parser_v1.coffee', ->
it 'registers slugs for each input name', ->
modVersion = parser.parse baseText + 'recipe:; input:Delta, Echo, Foxtrot; pattern:...012...'
modVersion._slugs.should.eql ['charlie', 'delta', 'echo', 'foxtrot']
(s.item for s in modVersion._slugs).should.eql ['charlie', 'delta', 'echo', 'foxtrot']
describe 'pattern', ->
it 'adds "pattern" when present', ->
modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo; pattern:... .0. .1.'
modVersion.findRecipes('test__charlie')[0].pattern.should.equal '... .0. .1.'
modVersion.findRecipes(ItemSlug.slugify('charlie'))[0].pattern.should.equal '... .0. .1.'
it 'requires a "pattern" declaration', ->
func = -> parser.parse baseText + 'recipe:; input:Alpha, Bravo'
@@ -119,7 +120,7 @@ describe 'mod_version_parser_v1.coffee', ->
it 'computes the input stack sizes from the pattern', ->
modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo, Charlie; pattern:111 .0. 2.2'
recipe = modVersion.findRecipes('test__charlie')[0]
recipe = modVersion.findRecipes(ItemSlug.slugify('charlie'))[0]
recipe.input[0].quantity.should.equal 1
recipe.input[1].quantity.should.equal 3
recipe.input[2].quantity.should.equal 2
@@ -135,7 +136,7 @@ describe 'mod_version_parser_v1.coffee', ->
it 'adds "quantity" when present', ->
modVersion = parser.parse baseText + 'quantity: 2'
modVersion.findRecipes('test__charlie')[0].output[0].quantity.should.equal 2
modVersion.findRecipes(ItemSlug.slugify('charlie'))[0].output[0].quantity.should.equal 2
it 'does not allow a duplicate "quantity" declaration', ->
func = -> parser.parse baseText + 'quantity:1; quantity:2'
@@ -147,7 +148,7 @@ describe 'mod_version_parser_v1.coffee', ->
it 'assumes a quantity of 1 by default', ->
modVersion = parser.parse baseText
modVersion.findRecipes('test__charlie')[0].output[0].quantity.should.equal 1
modVersion.findRecipes(ItemSlug.slugify('charlie'))[0].output[0].quantity.should.equal 1
it 'does not allow "quantity" before recipe', ->
func = -> parser.parse 'item:Bravo; quantity:12; recipe:;'
@@ -160,18 +161,18 @@ describe 'mod_version_parser_v1.coffee', ->
it 'adds a single item as the default output', ->
modVersion = parser.parse baseText
stack = modVersion.findRecipes('test__bravo')[0].output[0]
stack.slug.should.equal 'test__bravo'
stack = modVersion.findRecipes(ItemSlug.slugify('bravo'))[0].output[0]
stack.itemSlug.qualified.should.equal 'test__bravo'
stack.quantity.should.equal 1
it 'can add multiple extras with quantities', ->
modVersion = parser.parse baseText + 'extras:2 Delta, 4 Echo'
output = modVersion.findRecipes('test__bravo')[0].output
output[0].slug.should.equal 'test__bravo'
output = modVersion.findRecipes(ItemSlug.slugify('bravo'))[0].output
output[0].itemSlug.qualified.should.equal 'test__bravo'
output[0].quantity.should.equal 1
output[1].slug.should.equal 'test__delta'
output[1].itemSlug.qualified.should.equal 'test__delta'
output[1].quantity.should.equal 2
output[2].slug.should.equal 'echo'
output[2].itemSlug.qualified.should.equal 'echo'
output[2].quantity.should.equal 4
it 'does not allow "extras" before "recipe"', ->
@@ -180,7 +181,9 @@ describe 'mod_version_parser_v1.coffee', ->
it 'registers slugs for each output name', ->
modVersion = parser.parse baseText + 'extras:Delta, Echo'
modVersion._slugs.should.eql ['bravo', 'charlie', 'delta', 'echo']
(s.qualified for s in modVersion._slugs).should.eql [
'test__bravo', 'test__delta', 'charlie', 'echo'
]
it 'does not allow a duplicate "extras" declaration', ->
func = -> parser.parse baseText + 'extras:Echo; extras:Delta'
@@ -193,17 +196,17 @@ describe 'mod_version_parser_v1.coffee', ->
it 'can add a single tool', ->
modVersion = parser.parse baseText + 'tools: Furnace'
modVersion.findRecipes('test__bravo')[0].tools[0].slug.should.equal 'furnace'
modVersion.findRecipes(ItemSlug.slugify('bravo'))[0].tools[0].itemSlug.item.should.equal 'furnace'
it 'can add multiple tools', ->
modVersion = parser.parse baseText + 'tools: Crafting Table, Furnace'
tools = modVersion.findRecipes('test__bravo')[0].tools
tools[0].slug.should.equal 'crafting_table'
tools[1].slug.should.equal 'furnace'
tools = modVersion.findRecipes(ItemSlug.slugify('bravo'))[0].tools
tools[0].itemSlug.item.should.equal 'crafting_table'
tools[1].itemSlug.item.should.equal 'furnace'
it 'registers slugs for each tool name', ->
modVersion = parser.parse baseText + 'tools: Crafting Table, Furnace'
modVersion._slugs.should.eql ['bravo', 'charlie', 'crafting_table', 'furnace']
(s.item for s in modVersion._slugs).should.eql ['bravo', 'charlie', 'crafting_table', 'furnace']
it 'does not allow a duplicate "tools" declaration', ->
func = -> parser.parse baseText + 'tools:Crafting Table; tools:Furnace'
@@ -245,6 +248,4 @@ describe 'mod_version_parser_v1.coffee', ->
actual = CommandParserVersionBase.simplify text
expected = CommandParserVersionBase.simplify baseText
logger.debug "actual:\n>>>#{actual}<<<\n\n\n"
logger.debug "expected:\n>>>#{expected}<<<"
actual.should.equal expected
+24 -14
View File
@@ -5,9 +5,10 @@ Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
Item = require '../src/scripts/models/item'
Recipe = require '../src/scripts/models/recipe'
Stack = require '../src/scripts/models/stack'
Item = require '../src/scripts/models/item'
ItemSlug = require '../src/scripts/models/item_slug'
Recipe = require '../src/scripts/models/recipe'
Stack = require '../src/scripts/models/stack'
########################################################################################################################
@@ -20,7 +21,10 @@ describe 'recipe.coffee', ->
describe 'constructor', ->
beforeEach ->
input = [ new Stack(slug:'iron_gear'), new Stack(slug:'gold_ingot', quantity:4) ]
input = [
new Stack(itemSlug:new ItemSlug('iron_gear')),
new Stack(itemSlug:new ItemSlug('gold_ingot'), quantity:4)
]
pattern = '.1. 101 .1.'
it 'requires input', ->
@@ -31,29 +35,32 @@ describe 'recipe.coffee', ->
it 'requires either outputs or a slug', ->
f = -> new Recipe input:input, pattern:pattern
expect(f).to.throw 'attributes.slug or attributes.output is required'
expect(f).to.throw 'attributes.itemSlug or attributes.output is required'
it 'creates default output', ->
recipe = new Recipe slug:'gold_gear', input:input, pattern:pattern
recipe = new Recipe itemSlug:ItemSlug.slugify('gold_gear'), input:input, pattern:pattern
recipe.output.length.should.equal 1
recipe.output[0].slug.should.equal 'gold_gear'
recipe.output[0].itemSlug.qualified.should.equal 'gold_gear'
recipe.output[0].quantity.should.equal 1
it 'assigns a default slug', ->
recipe = new Recipe input:input, pattern:pattern, output:[new Stack slug:'gold_gear']
recipe.slug.should.equal 'gold_gear'
recipe = new Recipe input:input, pattern:pattern, output:[new Stack itemSlug:ItemSlug.slugify('gold_gear')]
recipe.itemSlug.qualified.should.equal 'gold_gear'
describe 'getItemSlugAt', ->
beforeEach ->
input = [ new Stack(slug:'iron_gear'), new Stack(slug:'gold_ingot', quantity:4) ]
recipe = new Recipe slug:'gold_gear', input:input, pattern:'.1. 101 .1.'
input = [
new Stack itemSlug:ItemSlug.slugify('iron_gear')
new Stack itemSlug:ItemSlug.slugify('gold_ingot'), quantity:4
]
recipe = new Recipe itemSlug:'gold_gear', input:input, pattern:'.1. 101 .1.'
it 'returns the proper item for an early slot', ->
recipe.getItemSlugAt(1).should.equal 'gold_ingot'
recipe.getItemSlugAt(1).qualified.should.equal 'gold_ingot'
it 'returns the proper item for a late slot', ->
recipe.getItemSlugAt(4).should.equal 'iron_gear'
recipe.getItemSlugAt(4).qualified.should.equal 'iron_gear'
it 'returns null for an invalid slot', ->
expect(recipe.getItemSlugAt(12)).to.be.null
@@ -61,7 +68,10 @@ describe 'recipe.coffee', ->
describe '_parsePattern', ->
beforeEach ->
recipe = new Recipe slug:'oak_wood_planks', input:[new Stack slug:'oak_wood'], pattern:'... .0. ...'
recipe = new Recipe
itemSlug: 'oak_wood_planks',
input: [new Stack itemSlug:new ItemSlug('oak_wood')],
pattern:'... .0. ...'
it 'normalizes invalid characters', ->
recipe._parsePattern('$$0 #() 010').should.equal '..0 ... 010'
+6 -5
View File
@@ -28,15 +28,16 @@ require '../src/scripts/underscore_mixins'
mocha.setup 'bdd'
require './crafting_plan.test'
# tests are roughly in order of how errors should be tackled
require './string_builder.test'
require './item_slug.test'
require './inventory.test'
require './inventory_parser.test'
require './recipe.test'
require './mod_version.test'
require './mod.test'
require './mod_pack.test'
require './mod_version.test'
require './parser_versions/mod_version_parser_v1.test'
require './recipe.test'
require './string_builder.test'
require './crafting_plan.test'
mocha.checkLeaks()
mocha.globals ['LiveReload']