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

uNmAnNeR / imaskjs / 7192548854

13 Dec 2023 08:24AM UTC coverage: 89.879% (+59.2%) from 30.682%
7192548854

push

github

uNmAnNeR
downgrade tsx to use loader for correct coverage

843 of 951 branches covered (0.0%)

Branch coverage included in aggregate %.

3926 of 4355 relevant lines covered (90.15%)

352.04 hits per line

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

98.57
/packages/imask/src/masked/pattern/cursor.ts
1
import { DIRECTION } from '../../core/utils';
1✔
2
import type MaskedPattern from '../pattern';
1✔
3
import type PatternBlock from './block';
1✔
4

1✔
5

1✔
6
type PatternCursorState = { offset: number, index: number, ok: boolean };
1✔
7

1✔
8
export default
1✔
9
class PatternCursor<Value> {
1✔
10
  declare masked: MaskedPattern<Value>;
8✔
11
  declare offset: number;
8✔
12
  declare index: number;
8✔
13
  declare ok: boolean;
8✔
14
  declare _log: PatternCursorState[];
8✔
15

8✔
16
  constructor (masked: MaskedPattern<Value>, pos: number) {
8✔
17
    this.masked = masked;
202✔
18
    this._log = [];
202✔
19

202✔
20
    const { offset, index } = masked._mapPosToBlock(pos) || (
202✔
21
      pos < 0 ?
3!
22
        // first
×
23
        { index: 0, offset: 0 } :
×
24
        // last
3✔
25
        { index: this.masked._blocks.length, offset: 0 }
3✔
26
    );
202✔
27
    this.offset = offset;
202✔
28
    this.index = index;
202✔
29
    this.ok = false;
202✔
30
  }
202✔
31

8✔
32
  get block (): PatternBlock {
8✔
33
    return this.masked._blocks[this.index];
3,114✔
34
  }
3,114✔
35

8✔
36
  get pos (): number {
8✔
37
    return this.masked._blockStartPos(this.index) + this.offset;
192✔
38
  }
192✔
39

8✔
40
  get state (): PatternCursorState {
8✔
41
    return { index: this.index, offset: this.offset, ok: this.ok };
642✔
42
  }
642✔
43

8✔
44
  set state (s: PatternCursorState) {
8✔
45
    Object.assign(this, s);
48✔
46
  }
48✔
47

8✔
48
  pushState () {
8✔
49
    this._log.push(this.state);
642✔
50
  }
642✔
51

8✔
52
  popState (): PatternCursorState | undefined {
8✔
53
    const s = this._log.pop();
48✔
54
    if (s) this.state = s;
48✔
55
    return s;
48✔
56
  }
48✔
57

8✔
58
  bindBlock () {
8✔
59
    if (this.block) return;
642✔
60
    if (this.index < 0) {
642✔
61
      this.index = 0;
35✔
62
      this.offset = 0;
35✔
63
    }
35✔
64
    if (this.index >= this.masked._blocks.length) {
152✔
65
      this.index = this.masked._blocks.length - 1;
6✔
66
      this.offset = (this.block as unknown as PatternBlock).displayValue.length; // TODO this is stupid type error, `block` depends on index that was changed above
6✔
67
    }
6✔
68
  }
642✔
69

8✔
70
  _pushLeft(fn: () => boolean | undefined): boolean {
8✔
71
    this.pushState();
545✔
72
    for (this.bindBlock(); 0<=this.index; --this.index, this.offset=this.block?.displayValue.length || 0) {
545✔
73
      if (fn()) return this.ok = true;
739✔
74
    }
739✔
75

545✔
76
    return this.ok = false;
545✔
77
  }
545✔
78

8✔
79
  _pushRight (fn: () => boolean | undefined): boolean {
8✔
80
    this.pushState();
97✔
81
    for (this.bindBlock(); this.index<this.masked._blocks.length; ++this.index, this.offset=0) {
97✔
82
      if (fn()) return this.ok = true;
167✔
83
    }
167✔
84

97✔
85
    return this.ok = false;
97✔
86
  }
97✔
87

8✔
88
  pushLeftBeforeFilled (): boolean {
8✔
89
    return this._pushLeft(() => {
181✔
90
      if (this.block.isFixed || !this.block.value) return;
332✔
91

332✔
92
      this.offset = this.block.nearestInputPos(this.offset, DIRECTION.FORCE_LEFT);
332✔
93
      if (this.offset !== 0) return true;
332✔
94
    });
181✔
95
  }
181✔
96

8✔
97
  pushLeftBeforeInput (): boolean {
8✔
98
    // cases:
183✔
99
    // filled input: 00|
183✔
100
    // optional empty input: 00[]|
183✔
101
    // nested block: XX<[]>|
183✔
102
    return this._pushLeft(() => {
183✔
103
      if (this.block.isFixed) return;
222✔
104

222✔
105
      this.offset = this.block.nearestInputPos(this.offset, DIRECTION.LEFT);
222✔
106
      return true;
174✔
107
    });
183✔
108
  }
183✔
109

8✔
110
  pushLeftBeforeRequired (): boolean {
8✔
111
    return this._pushLeft(() => {
181✔
112
      if (this.block.isFixed || this.block.isOptional && !this.block.value) return;
185✔
113

185✔
114
      this.offset = this.block.nearestInputPos(this.offset, DIRECTION.LEFT);
185✔
115
      return true;
170✔
116
    });
181✔
117
  }
181✔
118

8✔
119
  pushRightBeforeFilled (): boolean {
8✔
120
    return this._pushRight(() => {
28✔
121
      if (this.block.isFixed || !this.block.value) return;
57✔
122

57✔
123
      this.offset = this.block.nearestInputPos(this.offset, DIRECTION.FORCE_RIGHT);
57✔
124
      if (this.offset !== this.block.value.length) return true;
57✔
125
    });
28✔
126
  }
28✔
127

8✔
128
  pushRightBeforeInput (): boolean {
8✔
129
    return this._pushRight(() => {
42✔
130
      if (this.block.isFixed) return;
80✔
131

40✔
132
      // const o = this.offset;
40✔
133
      this.offset = this.block.nearestInputPos(this.offset, DIRECTION.NONE);
40✔
134
      // HACK cases like (STILL DOES NOT WORK FOR NESTED)
40✔
135
      // aa|X
40✔
136
      // aa<X|[]>X_    - this will not work
40✔
137
      // if (o && o === this.offset && this.block instanceof PatternInputDefinition) continue;
40✔
138
      return true;
40✔
139
    });
42✔
140
  }
42✔
141

8✔
142
  pushRightBeforeRequired (): boolean {
8✔
143
    return this._pushRight(() => {
27✔
144
      if (this.block.isFixed || this.block.isOptional && !this.block.value) return;
30✔
145

30✔
146
      // TODO check |[*]XX_
30✔
147
      this.offset = this.block.nearestInputPos(this.offset, DIRECTION.NONE);
30✔
148
      return true;
21✔
149
    });
27✔
150
  }
27✔
151
}
8✔
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