volleyballsimtypes 0.0.390 → 0.0.392

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,8 +18,8 @@ exports.MatchSetInputSchema = zod_1.z.object({
18
18
  id: zod_1.z.uuid(),
19
19
  order: orderSchema,
20
20
  isTieBreak: zod_1.z.boolean(),
21
- homePlayerPosition: zod_1.z.array(PlayerPositionSchema).max(12),
22
- awayPlayerPosition: zod_1.z.array(PlayerPositionSchema).max(12),
21
+ homePlayerPosition: zod_1.z.array(PlayerPositionSchema).max(14),
22
+ awayPlayerPosition: zod_1.z.array(PlayerPositionSchema).max(14),
23
23
  homeScore: nonNegInt,
24
24
  awayScore: nonNegInt,
25
25
  boxScores: zod_1.z.array(zod_1.z.custom((v) => v instanceof box_score_1.BoxScore, {
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const globals_1 = require("@jest/globals");
4
+ const designated_sub_z_1 = require("./designated-sub.z");
5
+ const energy_band_1 = require("../energy-band");
6
+ const pinch_condition_1 = require("../pinch-condition");
7
+ const test_helpers_1 = require("../../test-helpers");
8
+ (0, globals_1.describe)('SubBandSchema', () => {
9
+ (0, globals_1.it)('accepts every energy band and NEVER', () => {
10
+ const bands = [energy_band_1.EnergyBand.ENERGETIC, energy_band_1.EnergyBand.WORN, energy_band_1.EnergyBand.TIRED, energy_band_1.EnergyBand.EXHAUSTED, 'NEVER'];
11
+ for (const band of bands) {
12
+ (0, globals_1.expect)(designated_sub_z_1.SubBandSchema.safeParse(band).success).toBe(true);
13
+ }
14
+ });
15
+ (0, globals_1.it)('rejects an unknown band', () => {
16
+ (0, globals_1.expect)(designated_sub_z_1.SubBandSchema.safeParse('SLEEPY').success).toBe(false);
17
+ });
18
+ });
19
+ (0, globals_1.describe)('ConditionLogicSchema', () => {
20
+ (0, globals_1.it)('accepts ALL and ANY', () => {
21
+ (0, globals_1.expect)(designated_sub_z_1.ConditionLogicSchema.safeParse('ALL').success).toBe(true);
22
+ (0, globals_1.expect)(designated_sub_z_1.ConditionLogicSchema.safeParse('ANY').success).toBe(true);
23
+ });
24
+ (0, globals_1.it)('rejects anything else', () => {
25
+ (0, globals_1.expect)(designated_sub_z_1.ConditionLogicSchema.safeParse('SOMETIMES').success).toBe(false);
26
+ });
27
+ });
28
+ (0, globals_1.describe)('PinchConditionSchema', () => {
29
+ const valid = [
30
+ { type: pinch_condition_1.PinchConditionType.ASAP },
31
+ { type: pinch_condition_1.PinchConditionType.TEAM_SET_POINT, margin: 2, opponent: pinch_condition_1.OpponentRelation.EITHER },
32
+ { type: pinch_condition_1.PinchConditionType.OPPONENT_SET_POINT, margin: 1 },
33
+ { type: pinch_condition_1.PinchConditionType.SCORE_DIFF, direction: pinch_condition_1.ScoreDirection.TRAILING, points: 3 },
34
+ { type: pinch_condition_1.PinchConditionType.AFTER_ROTATIONS, rotations: 1 },
35
+ { type: pinch_condition_1.PinchConditionType.FROM_SET, set: 5 },
36
+ { type: pinch_condition_1.PinchConditionType.MIN_OWN_SCORE, score: 20 }
37
+ ];
38
+ (0, globals_1.it)('accepts a valid instance of every condition type', () => {
39
+ for (const condition of valid) {
40
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse(condition).success).toBe(true);
41
+ }
42
+ });
43
+ (0, globals_1.it)('rejects an unknown condition type', () => {
44
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: 'WHENEVER' }).success).toBe(false);
45
+ });
46
+ (0, globals_1.it)('rejects a condition missing its required field', () => {
47
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.TEAM_SET_POINT, opponent: pinch_condition_1.OpponentRelation.EITHER }).success).toBe(false);
48
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.SCORE_DIFF, direction: pinch_condition_1.ScoreDirection.LEADING }).success).toBe(false);
49
+ });
50
+ (0, globals_1.it)('enforces numeric bounds', () => {
51
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.TEAM_SET_POINT, margin: 0, opponent: pinch_condition_1.OpponentRelation.AHEAD }).success).toBe(false);
52
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.TEAM_SET_POINT, margin: 26, opponent: pinch_condition_1.OpponentRelation.AHEAD }).success).toBe(false);
53
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.AFTER_ROTATIONS, rotations: 7 }).success).toBe(false);
54
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.FROM_SET, set: 6 }).success).toBe(false);
55
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.MIN_OWN_SCORE, score: 41 }).success).toBe(false);
56
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.SCORE_DIFF, direction: pinch_condition_1.ScoreDirection.TRAILING, points: 0 }).success).toBe(false);
57
+ });
58
+ (0, globals_1.it)('rejects a non-integer numeric field', () => {
59
+ (0, globals_1.expect)(designated_sub_z_1.PinchConditionSchema.safeParse({ type: pinch_condition_1.PinchConditionType.FROM_SET, set: 2.5 }).success).toBe(false);
60
+ });
61
+ });
62
+ (0, globals_1.describe)('DesignatedSubSchema', () => {
63
+ const country = (0, test_helpers_1.makeCountry)();
64
+ const starter = (0, test_helpers_1.makePlayer)(country);
65
+ const bench = (0, test_helpers_1.makePlayer)(country);
66
+ (0, globals_1.it)('accepts a fatigue-mode entry with a band and bench', () => {
67
+ const res = designated_sub_z_1.DesignatedSubSchema.safeParse({
68
+ starter,
69
+ bench,
70
+ isPinchServer: false,
71
+ fatigueBand: energy_band_1.EnergyBand.TIRED
72
+ });
73
+ (0, globals_1.expect)(res.success).toBe(true);
74
+ });
75
+ (0, globals_1.it)('accepts a fatigue-mode entry with no bench (falls back to closest sub)', () => {
76
+ const res = designated_sub_z_1.DesignatedSubSchema.safeParse({
77
+ starter,
78
+ isPinchServer: false
79
+ });
80
+ (0, globals_1.expect)(res.success).toBe(true);
81
+ });
82
+ (0, globals_1.it)('accepts a pinch-mode entry with a bench server and conditions', () => {
83
+ const res = designated_sub_z_1.DesignatedSubSchema.safeParse({
84
+ starter,
85
+ bench,
86
+ isPinchServer: true,
87
+ conditions: [{ type: pinch_condition_1.PinchConditionType.ASAP }],
88
+ conditionLogic: 'ALL'
89
+ });
90
+ (0, globals_1.expect)(res.success).toBe(true);
91
+ });
92
+ (0, globals_1.it)('rejects a pinch-mode entry without a bench server', () => {
93
+ const res = designated_sub_z_1.DesignatedSubSchema.safeParse({
94
+ starter,
95
+ isPinchServer: true,
96
+ conditions: [{ type: pinch_condition_1.PinchConditionType.ASAP }]
97
+ });
98
+ (0, globals_1.expect)(res.success).toBe(false);
99
+ if (!res.success) {
100
+ (0, globals_1.expect)(res.error.issues.some(issue => issue.message === 'PINCH_SERVER_REQUIRES_BENCH')).toBe(true);
101
+ }
102
+ });
103
+ (0, globals_1.it)('rejects a pinch-mode entry with no conditions', () => {
104
+ const res = designated_sub_z_1.DesignatedSubSchema.safeParse({
105
+ starter,
106
+ bench,
107
+ isPinchServer: true,
108
+ conditions: []
109
+ });
110
+ (0, globals_1.expect)(res.success).toBe(false);
111
+ if (!res.success) {
112
+ (0, globals_1.expect)(res.error.issues.some(issue => issue.message === 'PINCH_SERVER_REQUIRES_CONDITIONS')).toBe(true);
113
+ }
114
+ });
115
+ (0, globals_1.it)('rejects a starter that is not a Player instance', () => {
116
+ const res = designated_sub_z_1.DesignatedSubSchema.safeParse({
117
+ starter: { id: 'not-a-player' },
118
+ isPinchServer: false
119
+ });
120
+ (0, globals_1.expect)(res.success).toBe(false);
121
+ });
122
+ });
@@ -15,8 +15,8 @@ export const MatchSetInputSchema = z.object({
15
15
  id: z.uuid(),
16
16
  order: orderSchema,
17
17
  isTieBreak: z.boolean(),
18
- homePlayerPosition: z.array(PlayerPositionSchema).max(12),
19
- awayPlayerPosition: z.array(PlayerPositionSchema).max(12),
18
+ homePlayerPosition: z.array(PlayerPositionSchema).max(14),
19
+ awayPlayerPosition: z.array(PlayerPositionSchema).max(14),
20
20
  homeScore: nonNegInt,
21
21
  awayScore: nonNegInt,
22
22
  boxScores: z.array(z.custom((v) => v instanceof BoxScore, {
@@ -0,0 +1,120 @@
1
+ import { describe, it, expect } from '@jest/globals';
2
+ import { ConditionLogicSchema, DesignatedSubSchema, PinchConditionSchema, SubBandSchema } from './designated-sub.z';
3
+ import { EnergyBand } from '../energy-band';
4
+ import { OpponentRelation, PinchConditionType, ScoreDirection } from '../pinch-condition';
5
+ import { makeCountry, makePlayer } from '../../test-helpers';
6
+ describe('SubBandSchema', () => {
7
+ it('accepts every energy band and NEVER', () => {
8
+ const bands = [EnergyBand.ENERGETIC, EnergyBand.WORN, EnergyBand.TIRED, EnergyBand.EXHAUSTED, 'NEVER'];
9
+ for (const band of bands) {
10
+ expect(SubBandSchema.safeParse(band).success).toBe(true);
11
+ }
12
+ });
13
+ it('rejects an unknown band', () => {
14
+ expect(SubBandSchema.safeParse('SLEEPY').success).toBe(false);
15
+ });
16
+ });
17
+ describe('ConditionLogicSchema', () => {
18
+ it('accepts ALL and ANY', () => {
19
+ expect(ConditionLogicSchema.safeParse('ALL').success).toBe(true);
20
+ expect(ConditionLogicSchema.safeParse('ANY').success).toBe(true);
21
+ });
22
+ it('rejects anything else', () => {
23
+ expect(ConditionLogicSchema.safeParse('SOMETIMES').success).toBe(false);
24
+ });
25
+ });
26
+ describe('PinchConditionSchema', () => {
27
+ const valid = [
28
+ { type: PinchConditionType.ASAP },
29
+ { type: PinchConditionType.TEAM_SET_POINT, margin: 2, opponent: OpponentRelation.EITHER },
30
+ { type: PinchConditionType.OPPONENT_SET_POINT, margin: 1 },
31
+ { type: PinchConditionType.SCORE_DIFF, direction: ScoreDirection.TRAILING, points: 3 },
32
+ { type: PinchConditionType.AFTER_ROTATIONS, rotations: 1 },
33
+ { type: PinchConditionType.FROM_SET, set: 5 },
34
+ { type: PinchConditionType.MIN_OWN_SCORE, score: 20 }
35
+ ];
36
+ it('accepts a valid instance of every condition type', () => {
37
+ for (const condition of valid) {
38
+ expect(PinchConditionSchema.safeParse(condition).success).toBe(true);
39
+ }
40
+ });
41
+ it('rejects an unknown condition type', () => {
42
+ expect(PinchConditionSchema.safeParse({ type: 'WHENEVER' }).success).toBe(false);
43
+ });
44
+ it('rejects a condition missing its required field', () => {
45
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.TEAM_SET_POINT, opponent: OpponentRelation.EITHER }).success).toBe(false);
46
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.SCORE_DIFF, direction: ScoreDirection.LEADING }).success).toBe(false);
47
+ });
48
+ it('enforces numeric bounds', () => {
49
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.TEAM_SET_POINT, margin: 0, opponent: OpponentRelation.AHEAD }).success).toBe(false);
50
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.TEAM_SET_POINT, margin: 26, opponent: OpponentRelation.AHEAD }).success).toBe(false);
51
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.AFTER_ROTATIONS, rotations: 7 }).success).toBe(false);
52
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.FROM_SET, set: 6 }).success).toBe(false);
53
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.MIN_OWN_SCORE, score: 41 }).success).toBe(false);
54
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.SCORE_DIFF, direction: ScoreDirection.TRAILING, points: 0 }).success).toBe(false);
55
+ });
56
+ it('rejects a non-integer numeric field', () => {
57
+ expect(PinchConditionSchema.safeParse({ type: PinchConditionType.FROM_SET, set: 2.5 }).success).toBe(false);
58
+ });
59
+ });
60
+ describe('DesignatedSubSchema', () => {
61
+ const country = makeCountry();
62
+ const starter = makePlayer(country);
63
+ const bench = makePlayer(country);
64
+ it('accepts a fatigue-mode entry with a band and bench', () => {
65
+ const res = DesignatedSubSchema.safeParse({
66
+ starter,
67
+ bench,
68
+ isPinchServer: false,
69
+ fatigueBand: EnergyBand.TIRED
70
+ });
71
+ expect(res.success).toBe(true);
72
+ });
73
+ it('accepts a fatigue-mode entry with no bench (falls back to closest sub)', () => {
74
+ const res = DesignatedSubSchema.safeParse({
75
+ starter,
76
+ isPinchServer: false
77
+ });
78
+ expect(res.success).toBe(true);
79
+ });
80
+ it('accepts a pinch-mode entry with a bench server and conditions', () => {
81
+ const res = DesignatedSubSchema.safeParse({
82
+ starter,
83
+ bench,
84
+ isPinchServer: true,
85
+ conditions: [{ type: PinchConditionType.ASAP }],
86
+ conditionLogic: 'ALL'
87
+ });
88
+ expect(res.success).toBe(true);
89
+ });
90
+ it('rejects a pinch-mode entry without a bench server', () => {
91
+ const res = DesignatedSubSchema.safeParse({
92
+ starter,
93
+ isPinchServer: true,
94
+ conditions: [{ type: PinchConditionType.ASAP }]
95
+ });
96
+ expect(res.success).toBe(false);
97
+ if (!res.success) {
98
+ expect(res.error.issues.some(issue => issue.message === 'PINCH_SERVER_REQUIRES_BENCH')).toBe(true);
99
+ }
100
+ });
101
+ it('rejects a pinch-mode entry with no conditions', () => {
102
+ const res = DesignatedSubSchema.safeParse({
103
+ starter,
104
+ bench,
105
+ isPinchServer: true,
106
+ conditions: []
107
+ });
108
+ expect(res.success).toBe(false);
109
+ if (!res.success) {
110
+ expect(res.error.issues.some(issue => issue.message === 'PINCH_SERVER_REQUIRES_CONDITIONS')).toBe(true);
111
+ }
112
+ });
113
+ it('rejects a starter that is not a Player instance', () => {
114
+ const res = DesignatedSubSchema.safeParse({
115
+ starter: { id: 'not-a-player' },
116
+ isPinchServer: false
117
+ });
118
+ expect(res.success).toBe(false);
119
+ });
120
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "volleyballsimtypes",
3
- "version": "0.0.390",
3
+ "version": "0.0.392",
4
4
  "description": "vbsim types",
5
5
  "main": "./dist/cjs/src/index.js",
6
6
  "module": "./dist/esm/src/index.js",