@@ -1160,6 +1160,104 @@ sugar
11601160 } ) ;
11611161 } ) ;
11621162
1163+ describe ( "Manual items" , ( ) => {
1164+ it ( "should add a manual item and recalculate ingredients" , ( ) => {
1165+ const shoppingList = new ShoppingList ( ) ;
1166+ shoppingList . addManualItem ( {
1167+ name : "bread" ,
1168+ quantities : [
1169+ {
1170+ quantity : { type : "fixed" , value : { type : "decimal" , decimal : 1 } } ,
1171+ unit : "loaf" ,
1172+ } ,
1173+ ] ,
1174+ } ) ;
1175+ expect ( shoppingList . manualItems ) . toHaveLength ( 1 ) ;
1176+ expect ( shoppingList . ingredients ) . toEqual ( [
1177+ {
1178+ name : "bread" ,
1179+ quantities : [
1180+ {
1181+ quantity : {
1182+ type : "fixed" ,
1183+ value : { type : "decimal" , decimal : 1 } ,
1184+ } ,
1185+ unit : "loaf" ,
1186+ } ,
1187+ ] ,
1188+ } ,
1189+ ] ) ;
1190+ } ) ;
1191+
1192+ it ( "should add a manual item without quantities" , ( ) => {
1193+ const shoppingList = new ShoppingList ( ) ;
1194+ shoppingList . addManualItem ( { name : "olive oil" } ) ;
1195+ expect ( shoppingList . manualItems ) . toHaveLength ( 1 ) ;
1196+ expect ( shoppingList . ingredients ) . toEqual ( [ { name : "olive oil" } ] ) ;
1197+ } ) ;
1198+
1199+ it ( "should merge a manual item with an existing recipe ingredient" , ( ) => {
1200+ const shoppingList = new ShoppingList ( ) ;
1201+ shoppingList . addRecipe ( recipe1 ) ;
1202+ shoppingList . addManualItem ( {
1203+ name : "flour" ,
1204+ quantities : [
1205+ {
1206+ quantity : {
1207+ type : "fixed" ,
1208+ value : { type : "decimal" , decimal : 50 } ,
1209+ } ,
1210+ unit : "g" ,
1211+ } ,
1212+ ] ,
1213+ } ) ;
1214+ const flour = shoppingList . ingredients . find ( ( i ) => i . name === "flour" ) ;
1215+ expect ( flour ?. quantities ?. [ 0 ] ) . toMatchObject < {
1216+ quantity : object ;
1217+ unit : string ;
1218+ } > ( {
1219+ quantity : { type : "fixed" , value : { type : "decimal" , decimal : 150 } } ,
1220+ unit : "g" ,
1221+ } ) ;
1222+ } ) ;
1223+
1224+ it ( "should remove a manual item and recalculate ingredients" , ( ) => {
1225+ const shoppingList = new ShoppingList ( ) ;
1226+ shoppingList . addManualItem ( { name : "bread" } ) ;
1227+ shoppingList . addManualItem ( { name : "olive oil" } ) ;
1228+ shoppingList . removeManualItem ( 0 ) ;
1229+ expect ( shoppingList . manualItems ) . toHaveLength ( 1 ) ;
1230+ expect ( shoppingList . manualItems [ 0 ] ! . name ) . toBe ( "olive oil" ) ;
1231+ expect ( shoppingList . ingredients ) . toEqual ( [ { name : "olive oil" } ] ) ;
1232+ } ) ;
1233+
1234+ it ( "should throw an error when removing a manual item with an invalid index" , ( ) => {
1235+ const shoppingList = new ShoppingList ( ) ;
1236+ shoppingList . addManualItem ( { name : "bread" } ) ;
1237+ expect ( ( ) => shoppingList . removeManualItem ( 1 ) ) . toThrow (
1238+ "Index out of bounds" ,
1239+ ) ;
1240+ expect ( ( ) => shoppingList . removeManualItem ( - 1 ) ) . toThrow (
1241+ "Index out of bounds" ,
1242+ ) ;
1243+ } ) ;
1244+
1245+ it ( "should re-categorize after adding a manual item" , ( ) => {
1246+ const shoppingList = new ShoppingList ( `[Bakery]\nbread` ) ;
1247+ shoppingList . addManualItem ( { name : "bread" } ) ;
1248+ expect ( shoppingList . categories ?. Bakery ) . toBeDefined ( ) ;
1249+ expect ( shoppingList . categories ! . Bakery ! [ 0 ] ! . name ) . toBe ( "bread" ) ;
1250+ } ) ;
1251+
1252+ it ( "should re-categorize after removing a manual item" , ( ) => {
1253+ const shoppingList = new ShoppingList ( `[Bakery]\nbread` ) ;
1254+ shoppingList . addManualItem ( { name : "bread" } ) ;
1255+ shoppingList . addManualItem ( { name : "butter" } ) ;
1256+ shoppingList . removeManualItem ( 0 ) ;
1257+ expect ( shoppingList . categories ?. Bakery ) . toEqual ( [ ] ) ;
1258+ } ) ;
1259+ } ) ;
1260+
11631261 describe ( "Pantry integration" , ( ) => {
11641262 const pantryRecipe = new Recipe (
11651263 `Add @flour{200%g} and @sugar{100%g} and @eggs{3}.` ,
0 commit comments