BatchCalculator.spec.js (25553B)
1 import { beforeEach, test, expect } from 'vitest'; 2 import { shallowMount } from '@vue/test-utils'; 3 import BatchCalculator from '@/views/BatchCalculator.vue'; 4 import { defaultTargetSets } from '@/core/targets'; 5 import { detectDefaultUnitSystem } from '@/core/units'; 6 7 beforeEach(() => { 8 localStorage.clear(); 9 }); 10 11 test('should initialize regular options to default values', async () => { 12 // Initialize component 13 const wrapper = shallowMount(BatchCalculator); 14 15 // Assert regular options are initialized 16 expect(wrapper.findComponent({ name: 'pace-input' }).vm.modelValue).to.deep.equal({ 17 distanceValue: 5, 18 distanceUnit: 'kilometers', 19 time: 1200, 20 }); 21 expect(wrapper.findComponent({ name: 'time-input' }).vm.modelValue).to.equal(15); 22 expect(wrapper.findComponent({ name: 'integer-input' }).vm.modelValue).to.equal(20); 23 expect(wrapper.find('select[aria-label="Calculator"]').element.value).to.equal('workout'); 24 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.globalOptions).to.deep.equal({ 25 defaultUnitSystem: detectDefaultUnitSystem(), 26 racePredictionOptions: { 27 model: 'AverageModel', 28 riegelExponent: 1.06, 29 }, 30 }); 31 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.batchOptions).to.deep.equal({ 32 calculator: 'workout', 33 input: { 34 distanceValue: 5, 35 distanceUnit: 'kilometers', 36 time: 1200, 37 }, 38 increment: 15, 39 label: '', 40 rows: 20, 41 }); 42 }); 43 44 test('should initialize calculator options to default values', async () => { 45 // Initialize component 46 const wrapper = shallowMount(BatchCalculator); 47 48 // Assert pace calculator options are initialized 49 await wrapper.find('select[aria-label="Calculator"]').setValue('pace'); 50 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 51 input: { 52 distanceValue: 5, 53 distanceUnit: 'kilometers', 54 time: 1200, 55 }, 56 selectedTargetSet: '_pace_targets', 57 }); 58 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 59 .to.deep.equal(defaultTargetSets._pace_targets.targets); 60 61 // Assert race calculator options are loaded 62 await wrapper.find('select[aria-label="Calculator"]').setValue('race'); 63 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 64 input: { 65 distanceValue: 5, 66 distanceUnit: 'kilometers', 67 time: 1200, 68 }, 69 selectedTargetSet: '_race_targets', 70 }); 71 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 72 .to.deep.equal(defaultTargetSets._race_targets.targets); 73 74 // Assert workout calculator options are loaded 75 await wrapper.find('select[aria-label="Calculator"]').setValue('workout'); 76 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 77 customTargetNames: false, 78 input: { 79 distanceValue: 5, 80 distanceUnit: 'kilometers', 81 time: 1200, 82 }, 83 selectedTargetSet: '_workout_targets', 84 }); 85 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 86 .to.deep.equal(defaultTargetSets._workout_targets.targets); 87 }); 88 89 test('should load regular options from localStorage', async () => { 90 // Initialize localStorage 91 localStorage.setItem('running-tools.global-options', JSON.stringify({ 92 defaultUnitSystem: 'imperial', 93 racePredictionOptions: { 94 model: 'PurdyPointsModel', 95 riegelExponent: 1.2, 96 }, 97 })); 98 localStorage.setItem('running-tools.batch-calculator-options', JSON.stringify({ 99 calculator: 'race', 100 increment: 32, 101 input: { 102 distanceValue: 2, 103 distanceUnit: 'miles', 104 time: 600, 105 }, 106 label: 'foo', 107 rows: 15, 108 })); 109 110 // Initialize component 111 const wrapper = shallowMount(BatchCalculator); 112 113 // Assert data loaded 114 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.globalOptions).to.deep.equal({ 115 defaultUnitSystem: 'imperial', 116 racePredictionOptions: { 117 model: 'PurdyPointsModel', 118 riegelExponent: 1.2, 119 }, 120 }); 121 122 // Assert options loaded 123 expect(wrapper.find('select[aria-label="Calculator"]').element.value).to.equal('race'); 124 expect(wrapper.findComponent({ name: 'pace-input' }).vm.modelValue).to.deep.equal({ 125 distanceValue: 2, 126 distanceUnit: 'miles', 127 time: 600, 128 }); 129 expect(wrapper.findComponent({ name: 'time-input' }).vm.modelValue).to.equal(32); 130 expect(wrapper.findComponent({ name: 'integer-input' }).vm.modelValue).to.equal(15); 131 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.batchOptions).to.deep.equal({ 132 calculator: 'race', 133 input: { 134 distanceValue: 2, 135 distanceUnit: 'miles', 136 time: 600, 137 }, 138 increment: 32, 139 label: 'foo', 140 rows: 15, 141 }); 142 }); 143 144 test('should load calculator options from localStorage', async () => { 145 // Initialize localStorage 146 const selectedTargetSets = [ 147 { 148 name: 'Pace targets #1', 149 targets: [ 150 { type: 'distance', distanceValue: 1, distanceUnit: 'miles' }, 151 ], 152 }, 153 { 154 name: 'Race targets #1', 155 targets: [ 156 { type: 'distance', distanceValue: 3, distanceUnit: 'miles' }, 157 ], 158 }, 159 { 160 name: 'Workout targets #1', 161 targets: [ 162 { 163 type: 'distance', distanceValue: 5, distanceUnit: 'miles', 164 splitValue: 1, splitUnit: 'miles' 165 }, 166 ], 167 }, 168 ]; 169 localStorage.setItem('running-tools.pace-calculator-target-sets', JSON.stringify({ 170 'A': selectedTargetSets[0], 171 'B': { 172 name: 'Pace targets #2', 173 targets: [ 174 { type: 'distance', distanceValue: 2, distanceUnit: 'miles' }, 175 ], 176 } 177 })); 178 localStorage.setItem('running-tools.race-calculator-target-sets', JSON.stringify({ 179 'C': selectedTargetSets[1], 180 'D': { 181 name: 'Race targets #2', 182 targets: [ 183 { type: 'distance', distanceValue: 4, distanceUnit: 'miles' }, 184 ], 185 } 186 })); 187 localStorage.setItem('running-tools.workout-calculator-target-sets', JSON.stringify({ 188 'E': selectedTargetSets[2], 189 'F': { 190 name: 'Workout targets #2', 191 targets: [ 192 { type: 'distance', distanceValue: 6, distanceUnit: 'miles' }, 193 ], 194 } 195 })); 196 localStorage.setItem('running-tools.pace-calculator-options', JSON.stringify({ 197 input: { 198 distanceValue: 1, 199 distanceUnit: 'miles', 200 time: 300, 201 }, 202 selectedTargetSet: 'A', 203 })); 204 localStorage.setItem('running-tools.race-calculator-options', JSON.stringify({ 205 input: { 206 distanceValue: 1.1, 207 distanceUnit: 'miles', 208 time: 310, 209 }, 210 selectedTargetSet: 'C', 211 })); 212 localStorage.setItem('running-tools.workout-calculator-options', JSON.stringify({ 213 customTargetNames: true, 214 input: { 215 distanceValue: 1.2, 216 distanceUnit: 'miles', 217 time: 320, 218 }, 219 selectedTargetSet: 'E', 220 })); 221 222 // Initialize component 223 const wrapper = shallowMount(BatchCalculator); 224 225 // Assert pace calculator options are loaded 226 await wrapper.find('select[aria-label="Calculator"]').setValue('pace'); 227 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 228 input: { 229 distanceValue: 1.0, 230 distanceUnit: 'miles', 231 time: 300, 232 }, 233 selectedTargetSet: 'A', 234 }); 235 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 236 .to.deep.equal(selectedTargetSets[0].targets); 237 238 // Assert race calculator options are loaded 239 await wrapper.find('select[aria-label="Calculator"]').setValue('race'); 240 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 241 input: { 242 distanceValue: 1.1, 243 distanceUnit: 'miles', 244 time: 310, 245 }, 246 selectedTargetSet: 'C', 247 }); 248 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 249 .to.deep.equal(selectedTargetSets[1].targets); 250 251 // Assert workout calculator options are loaded 252 await wrapper.find('select[aria-label="Calculator"]').setValue('workout'); 253 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 254 customTargetNames: true, 255 input: { 256 distanceValue: 1.2, 257 distanceUnit: 'miles', 258 time: 320, 259 }, 260 selectedTargetSet: 'E', 261 }); 262 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 263 .to.deep.equal(selectedTargetSets[2].targets); 264 }); 265 266 test('should save regular options to localStorage when modified', async () => { 267 // Initialize localStorage 268 localStorage.setItem('running-tools.default-unit-system', '"metric"'); 269 270 // Initialize component 271 const wrapper = shallowMount(BatchCalculator); 272 273 // Change default units setting 274 await wrapper.findComponent({ name: 'advanced-options-input' }).setValue({ 275 defaultUnitSystem: 'imperial', 276 racePredictionOptions: { 277 model: 'CameronModel', 278 riegelExponent: 1.30, 279 }, 280 }, 'globalOptions'); 281 282 // New default units should be saved to localStorage 283 expect(localStorage.getItem('running-tools.global-options')).to.equal(JSON.stringify({ 284 defaultUnitSystem: 'imperial', 285 racePredictionOptions: { 286 model: 'CameronModel', 287 riegelExponent: 1.30, 288 }, 289 })); 290 291 // Update input pace 292 await wrapper.findComponent({ name: 'pace-input' }).setValue({ 293 distanceValue: 2, 294 distanceUnit: 'miles', 295 time: 600, 296 }); 297 298 // Assert options saved 299 expect(localStorage.getItem('running-tools.batch-calculator-options')).to.equal(JSON.stringify({ 300 calculator: 'workout', 301 increment: 15, 302 input: { 303 distanceValue: 2, 304 distanceUnit: 'miles', 305 time: 600, 306 }, 307 label: '', 308 rows: 20, 309 })); 310 311 // Update increment value 312 await wrapper.findComponent({ name: 'time-input' }).setValue(32); 313 314 // Assert options saved 315 expect(localStorage.getItem('running-tools.batch-calculator-options')).to.equal(JSON.stringify({ 316 calculator: 'workout', 317 increment: 32, 318 input: { 319 distanceValue: 2, 320 distanceUnit: 'miles', 321 time: 600, 322 }, 323 label: '', 324 rows: 20, 325 })); 326 327 // Update number of rows 328 await wrapper.findComponent({ name: 'integer-input' }).setValue(15); 329 330 // Assert options saved 331 expect(localStorage.getItem('running-tools.batch-calculator-options')).to.equal(JSON.stringify({ 332 calculator: 'workout', 333 increment: 32, 334 input: { 335 distanceValue: 2, 336 distanceUnit: 'miles', 337 time: 600, 338 }, 339 label: '', 340 rows: 15, 341 })); 342 343 // Update batch column label 344 await wrapper.findComponent({ name: 'advanced-options-input' }).setValue({ 345 calculator: 'workout', 346 increment: 32, 347 input: { 348 distanceValue: 2, 349 distanceUnit: 'miles', 350 time: 600, 351 }, 352 label: 'foo', 353 rows: 15, 354 }, 'batch-options'); 355 356 // Assert options saved 357 expect(localStorage.getItem('running-tools.batch-calculator-options')).to.equal(JSON.stringify({ 358 calculator: 'workout', 359 increment: 32, 360 input: { 361 distanceValue: 2, 362 distanceUnit: 'miles', 363 time: 600, 364 }, 365 label: 'foo', 366 rows: 15, 367 })); 368 369 // Update active calculator 370 await wrapper.find('select[aria-label="Calculator"]').setValue('race'); 371 372 // Assert options saved 373 expect(localStorage.getItem('running-tools.batch-calculator-options')).to.equal(JSON.stringify({ 374 calculator: 'race', 375 increment: 32, 376 input: { 377 distanceValue: 2, 378 distanceUnit: 'miles', 379 time: 600, 380 }, 381 label: 'foo', 382 rows: 15, 383 })); 384 }); 385 386 test('should save calculator options to localStorage when modified', async () => { 387 // Initialize localStorage 388 const selectedTargetSets = [ 389 { 390 name: 'Pace targets #1', 391 targets: [ 392 { type: 'distance', distanceValue: 1, distanceUnit: 'miles' }, 393 ], 394 }, 395 { 396 name: 'Race targets #1', 397 targets: [ 398 { type: 'distance', distanceValue: 3, distanceUnit: 'miles' }, 399 ], 400 }, 401 { 402 name: 'Workout targets #1', 403 targets: [ 404 { 405 type: 'distance', distanceValue: 5, distanceUnit: 'miles', 406 splitValue: 1, splitUnit: 'miles' 407 }, 408 ], 409 }, 410 ]; 411 localStorage.setItem('running-tools.pace-calculator-target-sets', JSON.stringify({ 412 'A': selectedTargetSets[0], 413 'B': { 414 name: 'Pace targets #2', 415 targets: [ 416 { type: 'distance', distanceValue: 2, distanceUnit: 'miles' }, 417 ], 418 } 419 })); 420 localStorage.setItem('running-tools.pace-calculator-options', JSON.stringify({ 421 input: { 422 distanceValue: 1, 423 distanceUnit: 'miles', 424 time: 300, 425 }, 426 selectedTargetSet: 'B', 427 })); 428 localStorage.setItem('running-tools.race-calculator-target-sets', JSON.stringify({ 429 'C': selectedTargetSets[1], 430 'D': { 431 name: 'Race targets #2', 432 targets: [ 433 { type: 'distance', distanceValue: 4, distanceUnit: 'miles' }, 434 ], 435 } 436 })); 437 localStorage.setItem('running-tools.race-calculator-options', JSON.stringify({ 438 input: { 439 distanceValue: 1.1, 440 distanceUnit: 'miles', 441 time: 310, 442 }, 443 selectedTargetSet: 'D', 444 })); 445 localStorage.setItem('running-tools.workout-calculator-target-sets', JSON.stringify({ 446 'E': selectedTargetSets[2], 447 'F': { 448 name: 'Workout targets #2', 449 targets: [ 450 { type: 'distance', distanceValue: 6, distanceUnit: 'miles' }, 451 ], 452 } 453 })); 454 localStorage.setItem('running-tools.workout-calculator-options', JSON.stringify({ 455 customWorkoutNames: false, 456 input: { 457 distanceValue: 1.2, 458 distanceUnit: 'miles', 459 time: 320, 460 }, 461 selectedTargetSet: 'F', 462 })); 463 464 // Initialize component 465 const wrapper = shallowMount(BatchCalculator); 466 467 // Update pace calculator options X 468 await wrapper.find('select[aria-label="Calculator"]').setValue('pace'); 469 await wrapper.findComponent({ name: 'advanced-options-input' }).setValue({ 470 input: { 471 distanceValue: 1.0, 472 distanceUnit: 'miles', 473 time: 300, 474 }, 475 selectedTargetSet: 'A', 476 }, 'options'); 477 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 478 .to.deep.equal(selectedTargetSets[0].targets); 479 480 // Update race calculator options 481 await wrapper.find('select[aria-label="Calculator"]').setValue('race'); 482 await wrapper.findComponent({ name: 'advanced-options-input' }).setValue({ 483 input: { 484 distanceValue: 1.1, 485 distanceUnit: 'miles', 486 time: 310, 487 }, 488 selectedTargetSet: 'C', 489 }, 'options'); 490 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 491 .to.deep.equal(selectedTargetSets[1].targets); 492 493 // Update workout calculator options 494 await wrapper.find('select[aria-label="Calculator"]').setValue('workout'); 495 await wrapper.findComponent({ name: 'advanced-options-input' }).setValue({ 496 customTargetNames: true, 497 input: { 498 distanceValue: 1.2, 499 distanceUnit: 'miles', 500 time: 320, 501 }, 502 selectedTargetSet: 'E', 503 }, 'options'); 504 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.targets) 505 .to.deep.equal(selectedTargetSets[2].targets); 506 507 // Assert options saved to localStorage 508 expect(localStorage.getItem('running-tools.pace-calculator-options')).to.equal(JSON.stringify({ 509 input: { 510 distanceValue: 1.0, 511 distanceUnit: 'miles', 512 time: 300, 513 }, 514 selectedTargetSet: 'A', 515 })); 516 expect(localStorage.getItem('running-tools.race-calculator-options')).to.equal(JSON.stringify({ 517 input: { 518 distanceValue: 1.1, 519 distanceUnit: 'miles', 520 time: 310, 521 }, 522 selectedTargetSet: 'C', 523 })); 524 expect(localStorage.getItem('running-tools.workout-calculator-options')).to.equal(JSON.stringify({ 525 customTargetNames: true, 526 input: { 527 distanceValue: 1.2, 528 distanceUnit: 'miles', 529 time: 320, 530 }, 531 selectedTargetSet: 'E', 532 })); 533 }); 534 535 test('should pass correct input props to DoubleOutputTable', async () => { 536 // Initialize component 537 const wrapper = shallowMount(BatchCalculator); 538 539 // Assert that initial props are correct 540 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputDistance).to.deep.equal({ 541 distanceValue: 5, 542 distanceUnit: 'kilometers', 543 }); 544 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputTimes).to.deep.equal([ 545 1200, 1215, 1230, 1245, 1260, 1275, 1290, 1305, 1320, 1335, 546 1350, 1365, 1380, 1395, 1410, 1425, 1440, 1455, 1470, 1485, 547 ]); 548 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.label).to.equal('5 km'); 549 550 // Change input pace 551 await wrapper.findComponent({ name: 'pace-input' }).setValue({ 552 distanceValue: 2, 553 distanceUnit: 'miles', 554 time: 600, 555 }); 556 557 // Assert that the props are updated 558 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputDistance).to.deep.equal({ 559 distanceValue: 2, 560 distanceUnit: 'miles', 561 }); 562 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputTimes).to.deep.equal([ 563 600, 615, 630, 645, 660, 675, 690, 705, 720, 735, 564 750, 765, 780, 795, 810, 825, 840, 855, 870, 885, 565 ]); 566 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.label).to.equal('2 mi'); 567 568 // Change increment value 569 await wrapper.findComponent({ name: 'time-input' }).setValue(10); 570 571 // Assert that the props are updated 572 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputDistance).to.deep.equal({ 573 distanceValue: 2, 574 distanceUnit: 'miles', 575 }); 576 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputTimes).to.deep.equal([ 577 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 578 700, 710, 720, 730, 740, 750, 760, 770, 780, 790, 579 ]); 580 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.label).to.equal('2 mi'); 581 582 // Change number of rows 583 await wrapper.findComponent({ name: 'integer-input' }).setValue(15); 584 585 // Assert that the props are updated 586 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputDistance).to.deep.equal({ 587 distanceValue: 2, 588 distanceUnit: 'miles', 589 }); 590 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputTimes).to.deep.equal([ 591 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 592 ]); 593 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.label).to.equal('2 mi'); 594 595 // Enter custom batch column label 596 await wrapper.findComponent({ name: 'advanced-options-input' }).setValue({ 597 calculator: 'workout', 598 increment: 10, 599 input: { 600 distanceValue: 2, 601 distanceUnit: 'miles', 602 time: 600, 603 }, 604 label: 'foo', 605 rows: 15, 606 }, 'batchOptions'); 607 608 // Assert that the props are updated 609 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputDistance).to.deep.equal({ 610 distanceValue: 2, 611 distanceUnit: 'miles', 612 }); 613 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputTimes).to.deep.equal([ 614 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 615 ]); 616 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.label).to.equal('2 mi'); 617 618 // Enable target name customization 619 await wrapper.findComponent({ name: 'advanced-options-input' }).setValue({ 620 customTargetNames: true, 621 input: { 622 distanceValue: 5, 623 distanceUnit: 'kilometers', 624 time: 1200, 625 }, 626 selectedTargetSet: '_workout_targets', 627 }, 'options'); 628 629 // Assert that the props are updated 630 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputDistance).to.deep.equal({ 631 distanceValue: 2, 632 distanceUnit: 'miles', 633 }); 634 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputTimes).to.deep.equal([ 635 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 636 ]); 637 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.label).to.equal('foo'); 638 639 // Switch calculators 640 await wrapper.find('select[aria-label="Calculator"]').setValue('race'); 641 642 // Assert that the props are updated 643 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputDistance).to.deep.equal({ 644 distanceValue: 2, 645 distanceUnit: 'miles', 646 }); 647 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.inputTimes).to.deep.equal([ 648 600, 610, 620, 630, 640, 650, 660, 670, 680, 690, 700, 710, 720, 730, 740, 649 ]); 650 expect(wrapper.findComponent({ name: 'double-output-table' }).vm.label).to.equal('2 mi'); 651 }); 652 653 test('should correctly set AdvancedOptionsInput props', async () => { 654 // Initialize component 655 const wrapper = shallowMount(BatchCalculator); 656 657 // Set input pace and batch options 658 await wrapper.findComponent({ name: 'pace-input' }).setValue({ 659 distanceValue: 2, 660 distanceUnit: 'miles', 661 time: 600, 662 }); 663 await wrapper.findComponent({ name: 'time-input' }).setValue(32); 664 await wrapper.findComponent({ name: 'integer-input' }).setValue(15); 665 666 // Assert batch props are correct 667 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.batchOptions).to.deep.equal({ 668 calculator: 'workout', 669 increment: 32, 670 input: { 671 distanceValue: 2, 672 distanceUnit: 'miles', 673 time: 600, 674 }, 675 label: '', 676 rows: 15, 677 }); 678 679 // Assert props are correct for pace calculator 680 await wrapper.find('select[aria-label="Calculator"]').setValue('pace'); 681 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.type).to.equal('pace'); 682 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.globalOptions).to.deep.equal({ 683 defaultUnitSystem: 'imperial', 684 racePredictionOptions: { 685 model: 'AverageModel', 686 riegelExponent: 1.06, 687 }, 688 }); 689 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 690 input: { 691 distanceValue: 5, 692 distanceUnit: 'kilometers', 693 time: 1200, 694 }, 695 selectedTargetSet: '_pace_targets', 696 }); 697 698 // Assert props are correct for race calculator 699 await wrapper.find('select[aria-label="Calculator"]').setValue('race'); 700 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.type).to.equal('race'); 701 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.globalOptions).to.deep.equal({ 702 defaultUnitSystem: 'imperial', 703 racePredictionOptions: { 704 model: 'AverageModel', 705 riegelExponent: 1.06, 706 }, 707 }); 708 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 709 input: { 710 distanceValue: 5, 711 distanceUnit: 'kilometers', 712 time: 1200, 713 }, 714 selectedTargetSet: '_race_targets', 715 }); 716 717 // Assert props are correct for workout calculator 718 await wrapper.find('select[aria-label="Calculator"]').setValue('workout'); 719 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.type).to.equal('workout'); 720 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.globalOptions).to.deep.equal({ 721 defaultUnitSystem: 'imperial', 722 racePredictionOptions: { 723 model: 'AverageModel', 724 riegelExponent: 1.06, 725 }, 726 }); 727 expect(wrapper.findComponent({ name: 'advanced-options-input' }).vm.options).to.deep.equal({ 728 customTargetNames: false, 729 input: { 730 distanceValue: 5, 731 distanceUnit: 'kilometers', 732 time: 1200, 733 }, 734 selectedTargetSet: '_workout_targets', 735 }); 736 }); 737 738 test('should correctly calculate outputs', async () => { 739 // Initialize localStorage 740 localStorage.setItem('running-tools.global-options', JSON.stringify({ 741 defaultUnitSystem: 'imperial', 742 racePredictionOptions: { 743 model: 'PurdyPointsModel', 744 riegelExponent: 1.2, 745 }, 746 })); 747 localStorage.setItem('running-tools.race-calculator-options', JSON.stringify({ 748 input: { 749 distanceValue: 1.1, 750 distanceUnit: 'miles', 751 time: 310, 752 }, 753 selectedTargetSet: '_race_targets', 754 })); 755 localStorage.setItem('running-tools.workout-calculator-options', JSON.stringify({ 756 customTargetNames: false, 757 input: { 758 distanceValue: 1.2, 759 distanceUnit: 'miles', 760 time: 320, 761 }, 762 selectedTargetSet: '_workout_targets', 763 })); 764 765 // Initialize component 766 const wrapper = shallowMount(BatchCalculator); 767 const input = { distanceValue: 2, distanceUnit: 'miles', time: 600 }; 768 769 // Assert pace outputs are calculated correctly 770 await wrapper.find('select[aria-label="Calculator"]').setValue('pace'); 771 let calculate = wrapper.findComponent({ name: 'double-output-table' }).vm.calculateResult; 772 expect(calculate(input, { type: 'time', time: 3600 })).to.deep.equal({ 773 key: '12.00 mi', 774 value: '1:00:00', 775 pace: '5:00 / mi', 776 sort: 3600, 777 result: 'key', 778 }); 779 780 // Assert race outputs are calculated correctly 781 await wrapper.find('select[aria-label="Calculator"]').setValue('race'); 782 calculate = wrapper.findComponent({ name: 'double-output-table' }).vm.calculateResult; 783 expect(calculate(input, { type: 'time', time: 3600 })).to.deep.equal({ 784 key: '10.93 mi', 785 value: '1:00:00', 786 pace: '5:29 / mi', 787 sort: 3600, 788 result: 'key', 789 }); 790 791 // Assert workout outputs are calculated correctly 792 await wrapper.find('select[aria-label="Calculator"]').setValue('workout'); 793 calculate = wrapper.findComponent({ name: 'double-output-table' }).vm.calculateResult; 794 const workoutTarget = { type: 'time', time: 3600, splitValue: 1, splitUnit: 'miles' }; 795 const result = calculate(input, workoutTarget); 796 expect(result.key).to.equal('1 mi @ 1:00:00'); 797 expect(result.value).to.equal('5:29'); 798 expect(result.pace).to.equal(''); 799 expect(result.sort).to.be.closeTo(329.48, 0.01); 800 expect(result.result).to.equal('value'); 801 });