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.
- package/dist/cjs/src/service/match/schemas/match-set.z.js +2 -2
- package/dist/cjs/src/service/team/schemas/designated-sub.z.test.d.ts +1 -0
- package/dist/cjs/src/service/team/schemas/designated-sub.z.test.js +122 -0
- package/dist/esm/src/service/match/schemas/match-set.z.js +2 -2
- package/dist/esm/src/service/team/schemas/designated-sub.z.test.d.ts +1 -0
- package/dist/esm/src/service/team/schemas/designated-sub.z.test.js +120 -0
- package/package.json +1 -1
|
@@ -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(
|
|
22
|
-
awayPlayerPosition: zod_1.z.array(PlayerPositionSchema).max(
|
|
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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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(
|
|
19
|
-
awayPlayerPosition: z.array(PlayerPositionSchema).max(
|
|
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 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
+
});
|