import 'package:rimworld_modman/mod.dart'; import 'package:rimworld_modman/mod_list.dart'; import 'package:test/test.dart'; Mod makeDummy() { return Mod( name: 'Dummy Mod', id: 'dummy', path: '', versions: ["1.5"], description: '', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 0, isBaseGame: false, isExpansion: false, enabled: false, ); } void main() { test('Mods should be sorted by size while respecting constraints', () { final list = ModList(); list.mods = { 'dubwise.rimatomics': makeDummy().copyWith( id: 'dubwise.rimatomics', name: 'Dubs Rimatomics', enabled: true, size: 1563, dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], ), 'brrainz.justignoremepassing': makeDummy().copyWith( id: 'brrainz.justignoremepassing', name: 'Just Ignore Me Passing', enabled: true, size: 28, dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], ), 'brrainz.harmony': makeDummy().copyWith( id: 'brrainz.harmony', name: 'Harmony', enabled: true, size: 17, dependencies: [], loadAfter: [], loadBefore: ['ludeon.rimworld'], incompatibilities: [], ), 'jecrell.doorsexpanded': makeDummy().copyWith( id: 'jecrell.doorsexpanded', name: 'Doors Expanded', enabled: true, size: 765, dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], ), 'dubwise.rimefeller': makeDummy().copyWith( id: 'dubwise.rimefeller', name: 'Rimefeller', enabled: true, size: 744, dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], ), 'neronix17.toolbox': makeDummy().copyWith( id: 'neronix17.toolbox', name: 'Tabula Rasa', enabled: true, size: 415, dependencies: [], loadAfter: [ 'brrainz.harmony', 'ludeon.rimworld', 'ludeon.rimworld.royalty', 'ludeon.rimworld.ideology', 'ludeon.rimworld.biotech', 'ludeon.rimworld.anomaly', 'unlimitedhugs.hugslib', 'erdelf.humanoidalienraces', ], loadBefore: [], incompatibilities: [], ), 'automatic.bionicicons': makeDummy().copyWith( id: 'automatic.bionicicons', name: 'Bionic icons', enabled: true, size: 365, dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], ), 'lwm.deepstorage': makeDummy().copyWith( id: 'lwm.deepstorage', name: "LWM's Deep Storage", enabled: true, size: 256, dependencies: [], loadAfter: [ 'brrainz.harmony', 'ludeon.rimworld.core', 'rimfridge.kv.rw', 'mlie.cannibalmeals', ], loadBefore: ['com.github.alandariva.moreplanning'], incompatibilities: [], ), 'dubwise.dubsmintmenus': makeDummy().copyWith( id: 'dubwise.dubsmintmenus', name: 'Dubs Mint Menus', enabled: true, size: 190, dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], ), 'dubwise.dubsmintminimap': makeDummy().copyWith( id: 'dubwise.dubsmintminimap', name: 'Dubs Mint Minimap', enabled: true, size: 190, dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], ), 'ludeon.rimworld': makeDummy().copyWith( id: 'ludeon.rimworld', name: 'RimWorld', enabled: true, size: 0, dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], isBaseGame: true, ), 'ludeon.rimworld.royalty': makeDummy().copyWith( id: 'ludeon.rimworld.royalty', name: 'RimWorld Royalty', enabled: true, size: 0, dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], isExpansion: true, ), 'ludeon.rimworld.ideology': makeDummy().copyWith( id: 'ludeon.rimworld.ideology', name: 'RimWorld Ideology', enabled: true, size: 0, dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], isExpansion: true, ), 'ludeon.rimworld.biotech': makeDummy().copyWith( id: 'ludeon.rimworld.biotech', name: 'RimWorld Biotech', enabled: true, size: 0, dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], isExpansion: true, ), 'ludeon.rimworld.anomaly': makeDummy().copyWith( id: 'ludeon.rimworld.anomaly', name: 'RimWorld Anomaly', enabled: true, size: 0, dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], isExpansion: true, ), }; list.enableAll(); final result = list.generateLoadOrder(); final expected = [ 'brrainz.harmony', 'ludeon.rimworld', 'ludeon.rimworld.anomaly', 'ludeon.rimworld.biotech', 'ludeon.rimworld.ideology', 'ludeon.rimworld.royalty', 'dubwise.rimatomics', 'jecrell.doorsexpanded', 'dubwise.rimefeller', 'neronix17.toolbox', 'automatic.bionicicons', 'lwm.deepstorage', 'dubwise.dubsmintminimap', 'dubwise.dubsmintmenus', 'brrainz.justignoremepassing', ]; expect(result.errors, isEmpty); expect(result.loadOrder, equals(expected)); }); test('Prepatcher should load before Harmony', () { final list = ModList(); list.mods = { 'bs.betterlog': makeDummy().copyWith( id: 'bs.betterlog', name: 'Better Log - Fix your errors', enabled: true, size: 69, dependencies: [], loadAfter: [ 'brrainz.harmony', 'me.samboycoding.betterloading', 'zetrith.prepatcher', 'ludeon.rimworld', ], loadBefore: [ 'ludeon.rimworld.royalty', 'ludeon.rimworld.ideology', 'ludeon.rimworld.biotech', 'ludeon.rimworld.anomaly', 'bs.performance', 'unlimitedhugs.hugslib', ], incompatibilities: [], ), 'zetrith.prepatcher': makeDummy().copyWith( id: 'zetrith.prepatcher', name: 'Prepatcher', enabled: true, size: 21, loadBefore: ['ludeon.rimworld', 'brrainz.harmony'], ), 'brrainz.harmony': makeDummy().copyWith( id: 'brrainz.harmony', name: 'Harmony', enabled: true, size: 17, loadBefore: ['ludeon.rimworld'], ), 'ludeon.rimworld': makeDummy().copyWith( id: 'ludeon.rimworld', name: 'RimWorld', enabled: true, size: 0, isBaseGame: true, ), 'ludeon.rimworld.anomaly': makeDummy().copyWith( id: 'ludeon.rimworld.anomaly', name: 'RimWorld Anomaly', enabled: true, size: 0, loadAfter: ['ludeon.rimworld'], isExpansion: true, ), 'ludeon.rimworld.biotech': makeDummy().copyWith( id: 'ludeon.rimworld.biotech', name: 'RimWorld Biotech', enabled: true, size: 0, loadAfter: ['ludeon.rimworld'], isExpansion: true, ), 'ludeon.rimworld.ideology': makeDummy().copyWith( id: 'ludeon.rimworld.ideology', name: 'RimWorld Ideology', enabled: true, size: 0, loadAfter: ['ludeon.rimworld'], isExpansion: true, ), 'ludeon.rimworld.royalty': makeDummy().copyWith( id: 'ludeon.rimworld.royalty', name: 'RimWorld Royalty', enabled: true, size: 0, loadAfter: ['ludeon.rimworld'], isExpansion: true, ), }; list.enableAll(); final order = list.generateLoadOrder(); final expected = [ 'zetrith.prepatcher', 'brrainz.harmony', 'ludeon.rimworld', 'bs.betterlog', 'ludeon.rimworld.anomaly', 'ludeon.rimworld.royalty', 'ludeon.rimworld.ideology', 'ludeon.rimworld.biotech', ]; expect(order.loadOrder, equals(expected)); }); test('Expansions should load before most mods', () { final list = ModList(); list.mods = { 'bs.betterlog': makeDummy().copyWith( id: 'bs.betterlog', name: 'Better Log - Fix your errors', enabled: true, size: 69, dependencies: [], loadAfter: [ 'brrainz.harmony', 'me.samboycoding.betterloading', 'zetrith.prepatcher', 'ludeon.rimworld', ], loadBefore: [ 'ludeon.rimworld.royalty', 'ludeon.rimworld.ideology', 'ludeon.rimworld.biotech', 'ludeon.rimworld.anomaly', 'bs.performance', 'unlimitedhugs.hugslib', ], incompatibilities: [], ), 'zetrith.prepatcher': makeDummy().copyWith( id: 'zetrith.prepatcher', name: 'Prepatcher', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\2934420800', dependencies: [], loadAfter: [], loadBefore: ['ludeon.rimworld', 'brrainz.harmony'], incompatibilities: [], size: 21, isBaseGame: false, isExpansion: false, ), 'brrainz.harmony': makeDummy().copyWith( id: 'brrainz.harmony', name: 'Harmony', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\2009463077', dependencies: [], loadAfter: [], loadBefore: ['ludeon.rimworld'], incompatibilities: [], size: 17, isBaseGame: false, isExpansion: false, ), 'ludeon.rimworld': makeDummy().copyWith( id: 'ludeon.rimworld', name: 'RimWorld', path: '', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 0, isBaseGame: true, isExpansion: false, ), 'rah.rbse': makeDummy().copyWith( id: 'rah.rbse', name: 'RBSE', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\850429707', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 1729, isBaseGame: false, isExpansion: false, ), 'mlie.usethisinstead': makeDummy().copyWith( id: 'mlie.usethisinstead', name: 'Use This Instead', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\3396308787', dependencies: [], loadAfter: ['brrainz.harmony'], loadBefore: [], incompatibilities: [], size: 1651, isBaseGame: false, isExpansion: false, ), 'dubwise.rimatomics': makeDummy().copyWith( id: 'dubwise.rimatomics', name: 'Dubs Rimatomics', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\1127530465', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 1563, isBaseGame: false, isExpansion: false, ), 'jecrell.doorsexpanded': makeDummy().copyWith( id: 'jecrell.doorsexpanded', name: 'Doors Expanded', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\1316188771', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 765, isBaseGame: false, isExpansion: false, ), 'balistafreak.stopdropandroll': makeDummy().copyWith( id: 'balistafreak.stopdropandroll', name: 'Stop, Drop, And Roll! [BAL]', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\2362707956', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 755, isBaseGame: false, isExpansion: false, ), 'fluffy.animaltab': makeDummy().copyWith( id: 'fluffy.animaltab', name: 'Animal Tab', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\712141500', dependencies: ['brrainz.harmony'], loadAfter: [], loadBefore: [], incompatibilities: [], size: 752, isBaseGame: false, isExpansion: false, ), 'gt.sam.glittertech': makeDummy().copyWith( id: 'gt.sam.glittertech', name: 'Glitter Tech Classic', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\725576127', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 747, isBaseGame: false, isExpansion: false, ), 'dubwise.rimefeller': makeDummy().copyWith( id: 'dubwise.rimefeller', name: 'Rimefeller', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\1321849735', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 744, isBaseGame: false, isExpansion: false, ), 'darthcy.misc.morebetterdeepdrill': makeDummy().copyWith( id: 'darthcy.misc.morebetterdeepdrill', name: 'More and Better Deep Drill', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\3378527302', dependencies: [], loadAfter: ['brrainz.harmony', 'spdskatr.projectrimfactory'], loadBefore: [], incompatibilities: [], size: 738, isBaseGame: false, isExpansion: false, ), 'haplo.miscellaneous.training': makeDummy().copyWith( id: 'haplo.miscellaneous.training', name: 'Misc. Training', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\717575199', dependencies: [], loadAfter: ['haplo.miscellaneous.core'], loadBefore: [], incompatibilities: ['haplo.miscellaneous.trainingnotask'], size: 733, isBaseGame: false, isExpansion: false, ), 'linkolas.stabilize': makeDummy().copyWith( id: 'linkolas.stabilize', name: 'Stabilize', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\2023407836', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 627, isBaseGame: false, isExpansion: false, ), 'dubwise.dubsperformanceanalyzer.steam': makeDummy().copyWith( id: 'dubwise.dubsperformanceanalyzer.steam', name: 'Dubs Performance Analyzer', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\2038874626', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 570, isBaseGame: false, isExpansion: false, ), 'memegoddess.searchanddestroy': makeDummy().copyWith( id: 'memegoddess.searchanddestroy', name: 'Search and Destroy (Unofficial Update)', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\3232242247', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 495, isBaseGame: false, isExpansion: false, ), 'gogatio.mechanoidupgrades': makeDummy().copyWith( id: 'gogatio.mechanoidupgrades', name: 'Mechanoid Upgrades', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\3365118555', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 487, isBaseGame: false, isExpansion: false, ), 'issaczhuang.muzzleflash': makeDummy().copyWith( id: 'issaczhuang.muzzleflash', name: 'Muzzle Flash', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\2917732219', dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], size: 431, isBaseGame: false, isExpansion: false, ), 'smashphil.vehicleframework': makeDummy().copyWith( id: 'smashphil.vehicleframework', name: 'Vehicle Framework', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\3014915404', dependencies: [], loadAfter: ['brrainz.harmony'], loadBefore: [], incompatibilities: [], size: 426, isBaseGame: false, isExpansion: false, ), 'cabbage.rimcities': makeDummy().copyWith( id: 'cabbage.rimcities', name: 'RimCities', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\1775170117', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 421, isBaseGame: false, isExpansion: false, ), 'vis.staticquality': makeDummy().copyWith( id: 'vis.staticquality', name: 'Static Quality', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\2801204005', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 385, isBaseGame: false, isExpansion: false, ), 'automatic.bionicicons': makeDummy().copyWith( id: 'automatic.bionicicons', name: 'Bionic icons', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\1677616980', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 365, isBaseGame: false, isExpansion: false, ), 'vanillaexpanded.vanillatraitsexpanded': makeDummy().copyWith( id: 'vanillaexpanded.vanillatraitsexpanded', name: 'Vanilla Traits Expanded', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\2296404655', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 338, isBaseGame: false, isExpansion: false, ), 'tk421storm.ragdoll': makeDummy().copyWith( id: 'tk421storm.ragdoll', name: 'Ragdoll Physics', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\3179116177', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 329, isBaseGame: false, isExpansion: false, ), 'andromeda.nicehealthtab': makeDummy().copyWith( id: 'andromeda.nicehealthtab', name: 'Nice Health Tab', path: 'C:/Users/Administrator/Seafile/Games-RimWorld/294100\\3328729902', dependencies: [], loadAfter: [], loadBefore: [], incompatibilities: [], size: 319, isBaseGame: false, isExpansion: false, ), 'ludeon.rimworld.anomaly': makeDummy().copyWith( id: 'ludeon.rimworld.anomaly', name: 'RimWorld Anomaly', path: '', dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], size: 0, isBaseGame: false, isExpansion: true, ), 'ludeon.rimworld.biotech': makeDummy().copyWith( id: 'ludeon.rimworld.biotech', name: 'RimWorld Biotech', path: '', dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], size: 0, isBaseGame: false, isExpansion: true, ), 'ludeon.rimworld.ideology': makeDummy().copyWith( id: 'ludeon.rimworld.ideology', name: 'RimWorld Ideology', path: '', dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], size: 0, isBaseGame: false, isExpansion: true, ), 'ludeon.rimworld.royalty': makeDummy().copyWith( id: 'ludeon.rimworld.royalty', name: 'RimWorld Royalty', path: '', dependencies: [], loadAfter: ['ludeon.rimworld'], loadBefore: [], incompatibilities: [], size: 0, isBaseGame: false, isExpansion: true, ), }; list.enableAll(); final order = list.generateLoadOrder(); final expected = [ 'zetrith.prepatcher', 'brrainz.harmony', 'ludeon.rimworld', 'bs.betterlog', 'ludeon.rimworld.anomaly', 'ludeon.rimworld.biotech', 'ludeon.rimworld.ideology', 'ludeon.rimworld.royalty', ]; expect(order.loadOrder, equals(expected)); }); }