Skip to content

Commit d494b66

Browse files
author
Akos Kitta
committed
fix: aligned sketch folder validation based on the review request
Signed-off-by: Akos Kitta <[email protected]>
1 parent 7d1d6f0 commit d494b66

File tree

3 files changed

+69
-14
lines changed

3 files changed

+69
-14
lines changed

Diff for: arduino-ide-extension/src/common/protocol/sketches-service.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,11 @@ export namespace Sketch {
182182

183183
/**
184184
* `undefined` if the candidate cloud sketch folder name is valid. Otherwise, the validation error message.
185-
* Based on how https://create.arduino.cc/editor/ works.
186185
*/
187186
export function validateCloudSketchFolderName(
188187
candidate: string
189188
): string | undefined {
190-
return /^[0-9a-zA-Z_]{1,36}$/.test(candidate)
189+
return /^[0-9a-zA-Z]{1}[0-9a-zA-Z_\.-]{0,35}$/.test(candidate)
191190
? undefined
192191
: invalidCloudSketchFolderNameMessage;
193192
}
@@ -232,7 +231,10 @@ export namespace Sketch {
232231
*/
233232
export function toValidCloudSketchFolderName(candidate: string): string {
234233
return candidate
235-
? candidate.replace(/[^0-9a-zA-Z_]/g, defaultFallbackChar).slice(0, 36)
234+
? candidate
235+
.replace(/^[^0-9a-zA-Z]{1}/g, defaultFallbackFirstChar)
236+
.replace(/[^0-9a-zA-Z_\.-]/g, defaultFallbackChar)
237+
.slice(0, 36)
236238
: defaultSketchFolderName;
237239
}
238240

Diff for: arduino-ide-extension/src/test/browser/create-api.test.ts

+29
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,35 @@ describe('create-api', () => {
222222
expect(findByName(name, sketches)).to.be.not.undefined;
223223
expect(findByName(otherName, sketches)).to.be.not.undefined;
224224
});
225+
226+
['.', '-', '_'].map((char) => {
227+
it(`should create a new sketch with '${char}' in the sketch folder name although it's disallowed from the Create Editor`, async () => {
228+
const name = `sketch${char}`;
229+
const posixPath = toPosix(name);
230+
const newSketch = await createApi.createSketch(
231+
posixPath,
232+
'void setup(){} void loop(){}'
233+
);
234+
235+
expect(newSketch).to.be.not.undefined;
236+
expect(newSketch.name).to.be.equal(name);
237+
238+
let sketches = await createApi.sketches();
239+
let sketch = findByName(name, sketches);
240+
expect(sketch).to.be.not.undefined;
241+
// TODO: Cannot do deep equals because the Create API responses with different objects on POST and GET
242+
// `"libraries": [null]` vs `"libraries": []`
243+
// `"created_at": "2023-02-08T09:39:32.16994555Z"` vs `"created_at": "2023-02-08T09:39:32.169946Z"`
244+
// expect(newSketch).to.be.deep.equal(sketch);
245+
expect(newSketch.path).to.be.equal(sketch?.path);
246+
expect(newSketch.name).to.be.equal(sketch?.name);
247+
248+
await createApi.deleteSketch(sketch?.path!);
249+
sketches = await createApi.sketches();
250+
sketch = findByName(name, sketches);
251+
expect(sketch).to.be.undefined;
252+
});
253+
});
225254
});
226255

227256
// Using environment variables is recommended for testing but you can modify the module too.

Diff for: arduino-ide-extension/src/test/common/sketches-service.test.ts

+35-11
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ describe('sketch', () => {
4343
(
4444
[
4545
['sketch', true],
46-
['no-dashes', false],
47-
['no-dots', false],
46+
['can-contain-dashes', true],
47+
['can.contain.dots', true],
48+
['-cannot-start-with-dash', false],
49+
['.cannot.start.with.dash', false],
50+
['_cannot_start_with_underscore', false],
4851
['No Spaces', false],
49-
['_canStartWithUnderscore', true],
5052
['Invalid+Char.ino', false],
5153
['', false],
5254
['/', false],
@@ -79,6 +81,7 @@ describe('sketch', () => {
7981
'012345678901234567890123456789012345678901234567890123456789012',
8082
],
8183
['foo bar', 'foo_bar'],
84+
['_foobar', '0foobar'],
8285
['vAlid', 'vAlid'],
8386
].map(([input, expected]) =>
8487
toMapIt(input, expected, Sketch.toValidSketchFolderName)
@@ -102,6 +105,8 @@ describe('sketch', () => {
102105
'0123456789012345678901234567890123456789012' + epochSuffix,
103106
],
104107
['foo bar', 'foo_bar' + epochSuffix],
108+
['.foobar', '0foobar' + epochSuffix],
109+
['-fooBar', '0fooBar' + epochSuffix],
105110
['vAlid', 'vAlid' + epochSuffix],
106111
].map(([input, expected]) =>
107112
toMapIt(input, expected, (input: string) =>
@@ -113,15 +118,25 @@ describe('sketch', () => {
113118
describe('toValidCloudSketchFolderName', () => {
114119
[
115120
['sketch', 'sketch'],
116-
['can-contain-slash-and-dot.ino', 'can_contain_slash_and_dot_ino'],
121+
[
122+
'slash-and-dot-is-ok+but+no+plus.ino',
123+
'slash-and-dot-is-ok_but_no_plus.ino',
124+
],
117125
['regex++', 'regex__'],
118-
['dots...', 'dots___'],
126+
['dots...', 'dots...'],
127+
['.dots...', '0dots...'],
128+
['-dashes---', '0dashes---'],
129+
['_underscore___', '0underscore___'],
119130
['No Spaces', 'No_Spaces'],
120-
['_startsWithUnderscore', '_startsWithUnderscore'],
121-
['Invalid+Char.ino', 'Invalid_Char_ino'],
131+
['_startsWithUnderscore', '0startsWithUnderscore'],
132+
['Invalid+Char.ino', 'Invalid_Char.ino'],
122133
['', 'sketch'],
123-
['/', '_'],
124-
['//trash/', '__trash_'],
134+
['/', '0'],
135+
[
136+
'//////////////////////////////////////-/',
137+
'0___________________________________',
138+
],
139+
['//trash/', '0_trash_'],
125140
[
126141
'63Length_012345678901234567890123456789012345678901234567890123',
127142
'63Length_012345678901234567890123456',
@@ -140,6 +155,15 @@ function toMapIt(
140155
): Mocha.Test {
141156
return it(`should map the '${input}' ${
142157
cloud ? 'cloud ' : ''
143-
}sketch folder name to '${expected}'`, () =>
144-
expect(testMe(input)).to.be.equal(expected));
158+
}sketch folder name to '${expected}'`, () => {
159+
const actual = testMe(input);
160+
expect(actual).to.be.equal(expected);
161+
const errorMessage = Sketch.validateSketchFolderName(actual);
162+
try {
163+
expect(errorMessage).to.be.undefined;
164+
} catch (err) {
165+
console.log('HELLO', actual, errorMessage);
166+
throw err;
167+
}
168+
});
145169
}

0 commit comments

Comments
 (0)