• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

uNmAnNeR / imaskjs / 8121308078

02 Mar 2024 07:36AM UTC coverage: 92.411% (-0.01%) from 92.421%
8121308078

push

github

uNmAnNeR
fix #1007

976 of 1094 branches covered (89.21%)

Branch coverage included in aggregate %.

5 of 5 new or added lines in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

4479 of 4809 relevant lines covered (93.14%)

207.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.4
/packages/imask/src/masked/enum.ts
1
import MaskedPattern, { MaskedPatternState, type MaskedPatternOptions } from './pattern';
5✔
2
import { AppendFlags } from './base';
5✔
3
import IMask from '../core/holder';
5✔
4
import ChangeDetails from '../core/change-details';
5✔
5
import { DIRECTION } from '../core/utils';
5✔
6
import { TailDetails } from '../core/tail-details';
5✔
7
import ContinuousTailDetails from '../core/continuous-tail-details';
5✔
8

5✔
9

5✔
10
export
5✔
11
type MaskedEnumOptions = Omit<MaskedPatternOptions, 'mask'> & Pick<MaskedEnum, 'enum'> & Partial<Pick<MaskedEnum, 'matchValue'>>;
5✔
12

66✔
13
export
66✔
14
type MaskedEnumPatternOptions = MaskedPatternOptions & Partial<Pick<MaskedEnum, 'enum' | 'matchValue'>>;
5✔
15

1✔
16

1✔
17
/** Pattern which validates enum values */
10✔
18
export default
10✔
19
class MaskedEnum extends MaskedPattern {
10✔
20
  declare enum: Array<string>;
10✔
21
  /** Match enum value */
10✔
22
  declare matchValue: (enumStr: string, inputStr: string, matchFrom: number) => boolean;
10✔
23

10✔
24
  static DEFAULTS: typeof MaskedPattern.DEFAULTS & Pick<MaskedEnum, 'matchValue'> = {
10✔
25
    ...MaskedPattern.DEFAULTS,
20✔
26
    matchValue: (estr, istr, matchFrom) => estr.indexOf(istr, matchFrom) === matchFrom,
20✔
27
  };
20✔
28

20✔
29
  constructor (opts?: MaskedEnumOptions) {
20✔
30
    super({
57✔
31
      ...MaskedEnum.DEFAULTS,
20✔
32
      ...opts,
20✔
33
    } as MaskedPatternOptions); // mask will be created in _update
11✔
34
  }
10✔
35

10✔
36
  override updateOptions (opts: Partial<MaskedEnumOptions>) {
10✔
37
    super.updateOptions(opts);
10!
38
  }
×
39

×
40
  override _update (opts: Partial<MaskedEnumOptions>) {
11✔
41
    const { enum: enum_, ...eopts }: MaskedEnumPatternOptions = opts;
11✔
42

10✔
43
    if (enum_) {
10✔
44
      const lengths = enum_.map(e => e.length);
10✔
45
      const requiredLength = Math.min(...lengths);
20✔
46
      const optionalLength = Math.max(...lengths) - requiredLength;
5✔
47

2✔
48
      eopts.mask = '*'.repeat(requiredLength);
2✔
49
      if (optionalLength) eopts.mask += '[' + '*'.repeat(optionalLength) + ']';
5✔
UNCOV
50

×
51
      this.enum = enum_;
2✔
52
    }
2✔
53

2✔
54
    super._update(eopts);
2✔
55
  }
2✔
56

2✔
57
  override _appendCharRaw (ch: string, flags: AppendFlags<MaskedPatternState>={}): ChangeDetails {
2✔
58
    const matchFrom = Math.min(this.nearestInputPos(0, DIRECTION.FORCE_RIGHT), this.value.length);
3✔
59

3✔
60
    const matches = this.enum.filter(e => this.matchValue(e, this.unmaskedValue + ch, matchFrom));
5✔
61

9✔
62
    if (matches.length) {
9✔
63
      if (matches.length === 1) {
5✔
64
        this._forEachBlocksInRange(0, this.value.length, (b, bi) => {
1✔
65
          const mch = matches[0][bi];
1✔
66
          if (bi >= this.value.length || mch === b.value) return;
1✔
67

1✔
68
          b.reset();
1✔
69
          b._appendChar(mch, flags);
1✔
70
        });
1✔
71
      }
1✔
72

1✔
73
      const d = super._appendCharRaw(matches[0][this.value.length], flags);
1✔
74

1✔
75
      if (matches.length === 1) {
1✔
76
        matches[0].slice(this.unmaskedValue.length).split('').forEach(mch => d.aggregate(super._appendCharRaw(mch)));
1✔
77
      }
1✔
78

1✔
79
      return d;
1✔
80
    }
1✔
81

1✔
82
    return new ChangeDetails({ skip: !this.isComplete });
1✔
83
  }
1✔
84

1✔
85
  override extractTail (fromPos: number=0, toPos: number=this.displayValue.length): TailDetails {
1✔
86
    // just drop tail
1✔
87
    return new ContinuousTailDetails('', fromPos);
1✔
88
  }
1✔
89

1✔
90
  override remove (fromPos: number=0, toPos: number=this.displayValue.length): ChangeDetails {
1✔
91
    if (fromPos === toPos) return new ChangeDetails();
1✔
92

1✔
93
    const matchFrom = Math.min(super.nearestInputPos(0, DIRECTION.FORCE_RIGHT), this.value.length);
1✔
94

1✔
95
    let pos: number;
1✔
96
    for (pos = fromPos; pos >= 0; --pos) {
1✔
97
      const matches = this.enum.filter(e => this.matchValue(e, this.value.slice(matchFrom, pos), matchFrom));
1✔
98
      if (matches.length > 1) break;
1✔
99
    }
1✔
100

1✔
101
    const details = super.remove(pos, toPos);
1✔
102
    details.tailShift += pos - fromPos;
1✔
103

1✔
104
    return details;
1✔
105
  }
1✔
106

1✔
107
  override get isComplete (): boolean {
1✔
108
    return this.enum.indexOf(this.value) >= 0;
1✔
109
  }
1✔
110
}
1✔
111

1✔
112

1✔
113
IMask.MaskedEnum = MaskedEnum;
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc