transformation.test.ts 9.59 KB
Newer Older
Diegodlh's avatar
Diegodlh committed
1
2
3
import {
  DateTransformation,
  JoinTransformation,
Diegodlh's avatar
Diegodlh committed
4
  RangeTransformation,
Diegodlh's avatar
Diegodlh committed
5
  SplitTransformation,
Diegodlh's avatar
Diegodlh committed
6
  MatchTransformation,
Diegodlh's avatar
Diegodlh committed
7
8
9
10
11
  TransformationConfigTypeError,
} from "./transformation";

describe("Join tranformation", () => {
  const input = ["an", "array", "of", "strings"];
Diegodlh's avatar
Diegodlh committed
12
  it("joins input with default settings", async () => {
Diegodlh's avatar
Diegodlh committed
13
14
    const transformation = new JoinTransformation();
    const output = transformation.transform(input);
Diegodlh's avatar
Diegodlh committed
15
    expect(await output).toEqual(["an,array,of,strings"]);
Diegodlh's avatar
Diegodlh committed
16
  });
Diegodlh's avatar
Diegodlh committed
17
  it("joins input itemwise", async () => {
Diegodlh's avatar
Diegodlh committed
18
19
    const transformation = new JoinTransformation(true);
    const output = transformation.transform(input);
Diegodlh's avatar
Diegodlh committed
20
    expect(await output).toEqual(["a,n", "a,r,r,a,y", "o,f", "s,t,r,i,n,g,s"]);
Diegodlh's avatar
Diegodlh committed
21
  });
Diegodlh's avatar
Diegodlh committed
22
  it("joins input with custom separator", async () => {
Diegodlh's avatar
Diegodlh committed
23
24
    const transformation = new JoinTransformation(undefined, "|");
    const output = transformation.transform(input);
Diegodlh's avatar
Diegodlh committed
25
    expect(await output).toEqual(["an|array|of|strings"]);
Diegodlh's avatar
Diegodlh committed
26
  });
27
28
29
30
31
  it("json-stringifies to transformation definition", () => {
    const transformation = new JoinTransformation(true, " - ");
    expect(JSON.stringify(transformation)).toEqual(
      JSON.stringify({
        type: "join",
32
        config: " - ",
33
34
35
36
        itemwise: true,
      })
    );
  });
Diegodlh's avatar
Diegodlh committed
37
38
});

Diegodlh's avatar
Diegodlh committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
describe("Split transformation", () => {
  it("splits a single-string input", () => {
    const transformation = new SplitTransformation(false, "");
    return expect(transformation.transform(["string"])).resolves.toEqual([
      "s",
      "t",
      "r",
      "i",
      "n",
      "g",
    ]);
  });
  it("splits a single-string input, itemwise", () => {
    const transformation = new SplitTransformation(true, "");
    return expect(transformation.transform(["string"])).resolves.toEqual([
      "s",
      "t",
      "r",
      "i",
      "n",
      "g",
    ]);
  });
  it("splits a multiple-string input", () => {
    const transformation = new SplitTransformation(false, "");
    return expect(transformation.transform(["one", "two"])).resolves.toEqual([
      "o",
      "n",
      "e",
      ",",
      "t",
      "w",
      "o",
    ]);
  });
  it("splits a multiple-string input, itemwise", () => {
    const transformation = new SplitTransformation(true, "");
    return expect(transformation.transform(["one", "two"])).resolves.toEqual([
      "o",
      "n",
      "e",
      "t",
      "w",
      "o",
    ]);
  });
});

Diegodlh's avatar
Diegodlh committed
87
describe("Date transformation", () => {
Diegodlh's avatar
Diegodlh committed
88
  it("parses English dates", async () => {
Diegodlh's avatar
Diegodlh committed
89
    const transformation = new DateTransformation();
Diegodlh's avatar
Diegodlh committed
90
    expect(await transformation.transform(["January 27, 2022"])).toEqual([
Diegodlh's avatar
Diegodlh committed
91
92
      "2022-01-27",
    ]);
Diegodlh's avatar
Diegodlh committed
93
    expect(await transformation.transform(["yesterday"])).toEqual([
Diegodlh's avatar
Diegodlh committed
94
95
96
      new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString().split("T")[0],
    ]);
  });
Diegodlh's avatar
Diegodlh committed
97
  it("parses Spanish dates", async () => {
Diegodlh's avatar
Diegodlh committed
98
    const transformation = new DateTransformation(undefined, "es");
Diegodlh's avatar
Diegodlh committed
99
    expect(await transformation.transform(["27 de enero de 2022"])).toEqual([
Diegodlh's avatar
Diegodlh committed
100
101
      "2022-01-27",
    ]);
Diegodlh's avatar
Diegodlh committed
102
    expect(await transformation.transform(["ayer"])).toEqual([
Diegodlh's avatar
Diegodlh committed
103
104
105
106
107
108
109
110
      new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString().split("T")[0],
    ]);
  });
  it("rejects unsupported locales", () => {
    expect(() => new DateTransformation(undefined, "xx" as never)).toThrow(
      TransformationConfigTypeError
    );
  });
Diegodlh's avatar
Diegodlh committed
111
  it("ignores unknown dates", async () => {
Diegodlh's avatar
Diegodlh committed
112
    const transformation = new DateTransformation();
Diegodlh's avatar
Diegodlh committed
113
114
115
    expect(await transformation.transform(["not a date"])).toEqual([
      "not a date",
    ]);
Diegodlh's avatar
Diegodlh committed
116
  });
Diegodlh's avatar
Diegodlh committed
117
  it("parses dates without a day", async () => {
Diegodlh's avatar
Diegodlh committed
118
    const transformation = new DateTransformation();
Diegodlh's avatar
Diegodlh committed
119
120
121
    expect(await transformation.transform(["January 2022"])).toEqual([
      "2022-01",
    ]);
Diegodlh's avatar
Diegodlh committed
122
123
  });
});
Diegodlh's avatar
Diegodlh committed
124
125
126

describe("Range transformation", () => {
  const input = ["zero", "one", "two", "three"];
Diegodlh's avatar
Diegodlh committed
127
  it("selects single item", async () => {
Diegodlh's avatar
Diegodlh committed
128
129
    const transformation = new RangeTransformation();
    transformation.config = "1";
Diegodlh's avatar
Diegodlh committed
130
    expect(await transformation.transform(input)).toEqual(["one"]);
Diegodlh's avatar
Diegodlh committed
131
    transformation.config = "1:1";
Diegodlh's avatar
Diegodlh committed
132
    expect(await transformation.transform(input)).toEqual(["one"]);
Diegodlh's avatar
Diegodlh committed
133
    transformation.config = "1,";
Diegodlh's avatar
Diegodlh committed
134
    expect(await transformation.transform(input)).toEqual(["one"]);
Diegodlh's avatar
Diegodlh committed
135
  });
Diegodlh's avatar
Diegodlh committed
136
  it("selects multiple single items", async () => {
Diegodlh's avatar
Diegodlh committed
137
138
    const transformation = new RangeTransformation();
    transformation.config = "1,0";
Diegodlh's avatar
Diegodlh committed
139
    expect(await transformation.transform(input)).toEqual(["one", "zero"]);
Diegodlh's avatar
Diegodlh committed
140
  });
Diegodlh's avatar
Diegodlh committed
141
  it("selects single range with start and end", async () => {
Diegodlh's avatar
Diegodlh committed
142
143
    const transformation = new RangeTransformation();
    transformation.config = "1:2";
Diegodlh's avatar
Diegodlh committed
144
    expect(await transformation.transform(input)).toEqual(["one", "two"]);
Diegodlh's avatar
Diegodlh committed
145
  });
Diegodlh's avatar
Diegodlh committed
146
  it("selects single range without end", async () => {
Diegodlh's avatar
Diegodlh committed
147
148
    const transformation = new RangeTransformation();
    transformation.config = "1:";
Diegodlh's avatar
Diegodlh committed
149
150
151
152
153
    expect(await transformation.transform(input)).toEqual([
      "one",
      "two",
      "three",
    ]);
Diegodlh's avatar
Diegodlh committed
154
  });
Diegodlh's avatar
Diegodlh committed
155
  it("selects single range without start", async () => {
Diegodlh's avatar
Diegodlh committed
156
157
    const transformation = new RangeTransformation();
    transformation.config = ":2";
Diegodlh's avatar
Diegodlh committed
158
159
160
161
162
    expect(await transformation.transform(input)).toEqual([
      "zero",
      "one",
      "two",
    ]);
Diegodlh's avatar
Diegodlh committed
163
  });
Diegodlh's avatar
Diegodlh committed
164
  it("selects multiple ranges", async () => {
Diegodlh's avatar
Diegodlh committed
165
166
    const transformation = new RangeTransformation();
    transformation.config = "1:2,:2, 1:";
Diegodlh's avatar
Diegodlh committed
167
    expect(await transformation.transform(input)).toEqual([
Diegodlh's avatar
Diegodlh committed
168
169
170
171
172
173
174
175
176
177
      "one",
      "two",
      "zero",
      "one",
      "two",
      "one",
      "two",
      "three",
    ]);
  });
Diegodlh's avatar
Diegodlh committed
178
  it("tolerates too wide ranges", async () => {
Diegodlh's avatar
Diegodlh committed
179
180
    const transformation = new RangeTransformation();
    transformation.config = "1:1000";
Diegodlh's avatar
Diegodlh committed
181
182
183
184
185
    expect(await transformation.transform(input)).toEqual([
      "one",
      "two",
      "three",
    ]);
Diegodlh's avatar
Diegodlh committed
186
    transformation.config = "100:1000";
Diegodlh's avatar
Diegodlh committed
187
    expect(await transformation.transform(input)).toEqual([]);
Diegodlh's avatar
Diegodlh committed
188
  });
Diegodlh's avatar
Diegodlh committed
189
  it("tolerates impossible ranges", async () => {
Diegodlh's avatar
Diegodlh committed
190
191
    const transformation = new RangeTransformation();
    transformation.config = "2:1";
Diegodlh's avatar
Diegodlh committed
192
    expect(await transformation.transform(input)).toEqual([]);
Diegodlh's avatar
Diegodlh committed
193
  });
Diegodlh's avatar
Diegodlh committed
194
  it("ignores empty range configurations", async () => {
Diegodlh's avatar
Diegodlh committed
195
196
    const transformation = new RangeTransformation();
    transformation.config = ",1:2,,1";
Diegodlh's avatar
Diegodlh committed
197
198
199
200
201
    expect(await transformation.transform(input)).toEqual([
      "one",
      "two",
      "one",
    ]);
Diegodlh's avatar
Diegodlh committed
202
    transformation.config = "";
Diegodlh's avatar
Diegodlh committed
203
    expect(await transformation.transform(input)).toEqual([]);
Diegodlh's avatar
Diegodlh committed
204
  });
Diegodlh's avatar
Diegodlh committed
205
206
207
208
209
  it("ignores empty ranges", async () => {
    const transformation = new RangeTransformation();
    transformation.config = "1000";
    expect(await transformation.transform(input)).toEqual([]);
  });
Diegodlh's avatar
Diegodlh committed
210
  it("rejects invalid range config", async () => {
Diegodlh's avatar
Diegodlh committed
211
212
213
214
215
216
217
218
219
220
221
222
    expect(() => new RangeTransformation(undefined, ":")).toThrow(
      TransformationConfigTypeError
    );
    const transformation = new RangeTransformation();
    expect(() => (transformation.config = ":")).toThrow(
      TransformationConfigTypeError
    );
    expect(() => (transformation.config = "1:2:3")).toThrow(
      TransformationConfigTypeError
    );
  });
});
Diegodlh's avatar
Diegodlh committed
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

describe("Match transformation", () => {
  it("extracts single occurrence of target substring", async () => {
    const transformation = new MatchTransformation();
    transformation.config = "matching";
    const input = ["a substring inside a string"];
    expect(await transformation.transform(input)).toEqual(["substring"]);
  });

  it("extracts multiple occurrences of target substring", async () => {
    const transformation = new MatchTransformation();
    transformation.config = "substring";
    const input = ["a substring and another substring inside a string"];
    expect(await transformation.transform(input)).toEqual([
      "substring",
      "substring",
    ]);
  });

  it("returns empty array for non-matching substring", async () => {
    const transformation = new MatchTransformation();
    transformation.config = "substring";
    const input = ["a string without target"];
    expect(await transformation.transform(input)).toEqual([]);
  });

  it("extracts single occurrence of target itemwise", async () => {
    const transformation = new MatchTransformation();
    transformation.config = "matching";
    const input = ["a matching string", "another matching string"];
    expect(await transformation.transform(input)).toEqual([
      "matching",
      "matching",
    ]);
  });

  it("ignores input items without target substring", async () => {
    const transformation = new MatchTransformation();
    transformation.config = "substring";
    const input = [
      "a string with substring",
      "a string without",
      "another with substring",
    ];
    expect(await transformation.transform(input)).toEqual([
      "substring",
      "substring",
    ]);
  });

  it("combines input before matching if itemwise off", async () => {
    const transformation = new MatchTransformation(false);
    transformation.config = "sub,string";
    const input = ["a sub", "string in combined string"];
    expect(await transformation.transform(input)).toEqual(["sub,string"]);
  });

280
  it("supports regular expressions between //, including flags", async () => {
Diegodlh's avatar
Diegodlh committed
281
    const transformation = new MatchTransformation(false);
282
283
    transformation.config = "/(sub)?string/i";
    const input = ["a Substring inside a string"];
Diegodlh's avatar
Diegodlh committed
284
    expect(await transformation.transform(input)).toEqual([
285
      "Substring",
Diegodlh's avatar
Diegodlh committed
286
287
288
      "string",
    ]);
  });
289
290
291
292
293
294
295

  it("accepts optional double quotes to force plain string matching", async () => {
    const transformation = new MatchTransformation(false);
    transformation.config = '"/(sub)?string/i"';
    const input = ["a Substring inside a string", "/(sub)?string/i"];
    expect(await transformation.transform(input)).toEqual(["/(sub)?string/i"]);
  });
Diegodlh's avatar
Diegodlh committed
296
});