Skip to content

Commit 9554809

Browse files
committed
improve validation
1 parent 5559257 commit 9554809

5 files changed

Lines changed: 215 additions & 48 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Also showcasing different output options
6262
# staging
6363
```
6464

65-
### Modes
65+
## Modes
6666

6767
- `fallback-to-default` - use default value when no match was found
6868
- `fallback-to-original` - use original key when no match was found

__tests__/main.test.ts

Lines changed: 182 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ let setFailedMock: jest.SpiedFunction<typeof core.setFailed>
1919
let setOutputMock: jest.SpiedFunction<typeof core.setOutput>
2020
let exportVariableMock: jest.SpiedFunction<typeof core.exportVariable>
2121

22-
describe('action', () => {
22+
describe('correct input values, successful cases', () => {
2323
beforeEach(() => {
2424
jest.clearAllMocks()
2525

@@ -31,7 +31,6 @@ describe('action', () => {
3131
})
3232

3333
it('strict string on 1st line', () => {
34-
// Set the action's inputs as return values from core.getInput()
3534
const input: { [name: string]: string } = {
3635
key: 'k1',
3736
map: 'k1:v1',
@@ -48,15 +47,10 @@ describe('action', () => {
4847
expect(setFailedMock).not.toHaveBeenCalled()
4948
expect(exportVariableMock).not.toHaveBeenCalled()
5049

51-
expect(setOutputMock).toHaveBeenNthCalledWith(
52-
1,
53-
'value',
54-
expect.stringMatching('v1')
55-
)
50+
expect(setOutputMock).toHaveBeenNthCalledWith(1, 'value', 'v1')
5651
})
5752

5853
it('strict string on 2nd line', () => {
59-
// Set the action's inputs as return values from core.getInput()
6054
const input: { [name: string]: string } = {
6155
key: 'k2',
6256
map: 'k1:v1\nk2:v2',
@@ -73,15 +67,10 @@ describe('action', () => {
7367
expect(setFailedMock).not.toHaveBeenCalled()
7468
expect(exportVariableMock).not.toHaveBeenCalled()
7569

76-
expect(setOutputMock).toHaveBeenNthCalledWith(
77-
1,
78-
'value',
79-
expect.stringMatching('v2')
80-
)
70+
expect(setOutputMock).toHaveBeenNthCalledWith(1, 'value', 'v2')
8171
})
8272

8373
it('regex string', () => {
84-
// Set the action's inputs as return values from core.getInput()
8574
const input: { [name: string]: string } = {
8675
key: 'staging-23',
8776
map: 'staging-\\d+:staging',
@@ -98,15 +87,10 @@ describe('action', () => {
9887
expect(setFailedMock).not.toHaveBeenCalled()
9988
expect(exportVariableMock).not.toHaveBeenCalled()
10089

101-
expect(setOutputMock).toHaveBeenNthCalledWith(
102-
1,
103-
'value',
104-
expect.stringMatching('staging')
105-
)
90+
expect(setOutputMock).toHaveBeenNthCalledWith(1, 'value', 'staging')
10691
})
10792

10893
it('mode fallback-to-original', () => {
109-
// Set the action's inputs as return values from core.getInput()
11094
const input: { [name: string]: string } = {
11195
key: 'sandbox-25',
11296
map: 'staging-d+:staging',
@@ -123,15 +107,10 @@ describe('action', () => {
123107
expect(setFailedMock).not.toHaveBeenCalled()
124108
expect(exportVariableMock).not.toHaveBeenCalled()
125109

126-
expect(setOutputMock).toHaveBeenNthCalledWith(
127-
1,
128-
'value',
129-
expect.stringMatching('sandbox-25')
130-
)
110+
expect(setOutputMock).toHaveBeenNthCalledWith(1, 'value', 'sandbox-25')
131111
})
132112

133113
it('mode fallback-to-default', () => {
134-
// Set the action's inputs as return values from core.getInput()
135114
const input: { [name: string]: string } = {
136115
key: 'sandbox-25',
137116
map: 'staging-d+:staging',
@@ -149,15 +128,10 @@ describe('action', () => {
149128
expect(setFailedMock).not.toHaveBeenCalled()
150129
expect(exportVariableMock).not.toHaveBeenCalled()
151130

152-
expect(setOutputMock).toHaveBeenNthCalledWith(
153-
1,
154-
'value',
155-
expect.stringMatching('default-value')
156-
)
131+
expect(setOutputMock).toHaveBeenNthCalledWith(1, 'value', 'default-value')
157132
})
158133

159134
it('outputs and separator', () => {
160-
// Set the action's inputs as return values from core.getInput()
161135
const input: { [name: string]: string } = {
162136
key: 'k1',
163137
map: 'k1|v1',
@@ -176,15 +150,185 @@ describe('action', () => {
176150
expect(setFailedMock).not.toHaveBeenCalled()
177151
expect(errorMock).not.toHaveBeenCalled()
178152

179-
expect(setOutputMock).toHaveBeenNthCalledWith(
153+
expect(setOutputMock).toHaveBeenNthCalledWith(1, 'value', 'v1')
154+
expect(exportVariableMock).toHaveBeenNthCalledWith(1, 'test', 'v1')
155+
})
156+
})
157+
158+
describe('input validation', () => {
159+
beforeEach(() => {
160+
jest.clearAllMocks()
161+
162+
errorMock = jest.spyOn(core, 'error').mockImplementation()
163+
getInputMock = jest.spyOn(core, 'getInput').mockImplementation()
164+
setFailedMock = jest.spyOn(core, 'setFailed').mockImplementation()
165+
setOutputMock = jest.spyOn(core, 'setOutput').mockImplementation()
166+
exportVariableMock = jest.spyOn(core, 'exportVariable').mockImplementation()
167+
})
168+
169+
it('empty key', () => {
170+
const input: { [name: string]: string } = {
171+
key: '',
172+
map: 'k1:v1'
173+
}
174+
getInputMock.mockImplementation(name => input[name])
175+
176+
main.run()
177+
expect(runMock).toHaveReturned()
178+
179+
expect(errorMock).not.toHaveBeenCalled()
180+
expect(exportVariableMock).not.toHaveBeenCalled()
181+
expect(setOutputMock).not.toHaveBeenCalled()
182+
183+
expect(setFailedMock).toHaveBeenNthCalledWith(1, 'Key is empty')
184+
})
185+
186+
it('empty map', () => {
187+
const input: { [name: string]: string } = {
188+
key: 'k1',
189+
map: ''
190+
}
191+
getInputMock.mockImplementation(name => input[name])
192+
193+
main.run()
194+
expect(runMock).toHaveReturned()
195+
196+
expect(errorMock).not.toHaveBeenCalled()
197+
expect(exportVariableMock).not.toHaveBeenCalled()
198+
expect(setOutputMock).not.toHaveBeenCalled()
199+
200+
expect(setFailedMock).toHaveBeenNthCalledWith(1, 'Map is empty')
201+
})
202+
203+
it('empty separator', () => {
204+
const input: { [name: string]: string } = {
205+
key: 'k1',
206+
map: 'k1:v1',
207+
separator: ''
208+
}
209+
getInputMock.mockImplementation(name => input[name])
210+
211+
main.run()
212+
expect(runMock).toHaveReturned()
213+
214+
expect(errorMock).not.toHaveBeenCalled()
215+
expect(exportVariableMock).not.toHaveBeenCalled()
216+
expect(setOutputMock).not.toHaveBeenCalled()
217+
218+
expect(setFailedMock).toHaveBeenNthCalledWith(1, 'Separator is empty')
219+
})
220+
221+
it('incorrect export_to - empty', () => {
222+
const input: { [name: string]: string } = {
223+
key: 'k1',
224+
map: 'k1:v1',
225+
separator: ':',
226+
export_to: ''
227+
}
228+
getInputMock.mockImplementation(name => input[name])
229+
230+
main.run()
231+
expect(runMock).toHaveReturned()
232+
233+
expect(errorMock).not.toHaveBeenCalled()
234+
expect(exportVariableMock).not.toHaveBeenCalled()
235+
expect(setOutputMock).not.toHaveBeenCalled()
236+
237+
expect(setFailedMock).toHaveBeenNthCalledWith(
238+
1,
239+
expect.stringMatching('Invalid mode')
240+
)
241+
})
242+
243+
it('incorrect export_to - invalid', () => {
244+
const input: { [name: string]: string } = {
245+
key: 'k1',
246+
map: 'k1:v1',
247+
separator: ':',
248+
export_to: 'env,invalid'
249+
}
250+
getInputMock.mockImplementation(name => input[name])
251+
252+
main.run()
253+
expect(runMock).toHaveReturned()
254+
255+
expect(errorMock).not.toHaveBeenCalled()
256+
expect(exportVariableMock).not.toHaveBeenCalled()
257+
expect(setOutputMock).not.toHaveBeenCalled()
258+
259+
expect(setFailedMock).toHaveBeenNthCalledWith(
180260
1,
181-
'value',
182-
expect.stringMatching('v1')
261+
expect.stringMatching('Invalid mode')
183262
)
184-
expect(exportVariableMock).toHaveBeenNthCalledWith(
263+
})
264+
265+
it('missing export_to_env_name', () => {
266+
const input: { [name: string]: string } = {
267+
key: 'k1',
268+
map: 'k1:v1',
269+
separator: ':',
270+
mode: 'strict',
271+
export_to: 'env',
272+
export_to_env_name: ''
273+
}
274+
getInputMock.mockImplementation(name => input[name])
275+
276+
main.run()
277+
expect(runMock).toHaveReturned()
278+
279+
expect(errorMock).not.toHaveBeenCalled()
280+
expect(exportVariableMock).not.toHaveBeenCalled()
281+
expect(setOutputMock).not.toHaveBeenCalled()
282+
283+
expect(setFailedMock).toHaveBeenNthCalledWith(
284+
1,
285+
expect.stringMatching('Empty export_to_env_name')
286+
)
287+
})
288+
289+
it('incorrect separator or map line - one piece', () => {
290+
const input: { [name: string]: string } = {
291+
key: 'k1',
292+
map: 'k1:v1',
293+
separator: '|',
294+
mode: 'strict',
295+
export_to: 'output'
296+
}
297+
getInputMock.mockImplementation(name => input[name])
298+
299+
main.run()
300+
expect(runMock).toHaveReturned()
301+
302+
expect(errorMock).not.toHaveBeenCalled()
303+
expect(exportVariableMock).not.toHaveBeenCalled()
304+
expect(setOutputMock).not.toHaveBeenCalled()
305+
306+
expect(setFailedMock).toHaveBeenNthCalledWith(
307+
1,
308+
expect.stringMatching('Pattern and value pair missing')
309+
)
310+
})
311+
312+
it('incorrect separator or map line - 3 pieces', () => {
313+
const input: { [name: string]: string } = {
314+
key: 'k1',
315+
map: 'k1:v1:v2',
316+
separator: ':',
317+
mode: 'strict',
318+
export_to: 'output'
319+
}
320+
getInputMock.mockImplementation(name => input[name])
321+
322+
main.run()
323+
expect(runMock).toHaveReturned()
324+
325+
expect(errorMock).not.toHaveBeenCalled()
326+
expect(exportVariableMock).not.toHaveBeenCalled()
327+
expect(setOutputMock).not.toHaveBeenCalled()
328+
329+
expect(setFailedMock).toHaveBeenNthCalledWith(
185330
1,
186-
'test',
187-
expect.stringMatching('v1')
331+
expect.stringMatching('Pattern and value pair missing')
188332
)
189333
})
190334
})

dist/index.js

Lines changed: 13 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,19 @@ export function run(): void {
1414
const export_to_env_name: string = core.getInput('export_to_env_name')
1515
const default_value: string = core.getInput('default')
1616

17-
// Validate the input
17+
// Validate input
18+
if (key === '') {
19+
throw new Error(`Key is empty`)
20+
}
21+
22+
if (map === '') {
23+
throw new Error(`Map is empty`)
24+
}
25+
26+
if (separator === '') {
27+
throw new Error(`Separator is empty`)
28+
}
29+
1830
const mode_pattern = /^(strict|fallback-to-original|fallback-to-default)$/
1931
if (!mode_pattern.test(mode)) {
2032
throw new Error(
@@ -29,7 +41,7 @@ export function run(): void {
2941
)
3042
}
3143

32-
if (export_to.includes('env') && export_to_env_name.trim() == '') {
44+
if (export_to.includes('env') && export_to_env_name == '') {
3345
throw new Error(
3446
`Empty export_to_env_name: when export_to contains log value is required`
3547
)
@@ -40,13 +52,15 @@ export function run(): void {
4052

4153
let result: string | undefined
4254

43-
const lines = map.trim().split(/\r?\n/)
55+
const lines = map.split(/\r?\n/)
4456

4557
for (const line of lines) {
4658
core.debug(`Line: ${line}`)
4759
const pair = line.split(separator) // Destructure key and value
4860
if (pair.length != 2) {
49-
throw new Error(`Key/value pair not found: ${line}`)
61+
throw new Error(
62+
`Pattern and value pair missing, incorrect map or separator: ${line}, separator ${separator}`
63+
)
5064
}
5165
const regex = new RegExp(`^${pair[0]}$`)
5266
core.debug(`RegExp: ${regex}`)

0 commit comments

Comments
 (0)