Freecodecamp: global flag in regular expression fails test

Created on 8 Dec 2019  路  9Comments  路  Source: freeCodeCamp/freeCodeCamp

Link to the challenge: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/regular-expressions/check-for-mixed-grouping-of-characters

Issue

Adding a global flag to the regular expression has the test fail for the first two assertions.

let myString = "Eleanor Roosevelt";
let myRegex = /(Franklin|Eleanor).*Roosevelt/g;
let result = myRegex.test(myString);

This can be confusing considering also how the challenge is introduced, since the code snippet explaining the concept shows the global flag being used.

let testStr = "Pumpkin";
let testRegex = /P(engu|umpk)in/g;
testRegex.test(testStr);

Suggestion

Update the code snippet introducing the challenge:

-let testRegex = /P(engu|umpk)in/g;
+let testRegex = /P(engu|umpk)in/;

However, since the global flag should not affect the outcome of the test (to what I can ascertain), a better suggestion would be to update the test itself, to account for its presence.

first timers only learn

All 9 comments

Thanks for the detailed report!

I think it would make sense to do both. The g isn't necessary, so it should not be there and it's not wrong, so we should not reject it.

It might be better to remove the global flag from the challenge example unless we also explain how test() works with the global flag and give some info on lastIndex.

I think in order to really know if we should fail the test when using the global flag we would have to consider how the code is supposed to run. Are we "emulating" that each test() is being run in isolation or are they executed one after the other.

const names = ['Franklin D. Roosevelt', 'Eleanor Roosevelt', 'Franklin Rosevelt'];
const myRegex = /(Franklin|Eleanor).*Roosevelt/g;

for (const name of names) {
  console.log(myRegex.test(name));
  // true, false, false
}

It might be better to remove the global flag from the challenge example unless we also explain how test() works with the global flag and give some info on lastIndex.

Agreed.

Are we "emulating" that each test() is being run in isolation or are they executed one after the other.

This challenge focuses on teaching the user about groups - the use of test over match seem incidental to me, as does the presence of the flag.

Also, the challenge asks you to make sure

the regex that you have created is checked against myString and either true or false is returned depending on whether the regex matches.

so it's only asking you to use test against myString once.

and it's not wrong, so we should not reject it.

But it is when the test is called multiple times on the same regex. Isn't this kind of the same as when users use global variables which end up causing the user's code to fail for all tests except the first because the the global variable does not get reset each time?

Isn't this kind of the same as when users use global variables which end up causing the user's code to fail for all tests except the first because the the global variable does not get reset each time?

Yeah, it's the same principle. However, unlike the DOM tests, JS tests are isolated and each one only calls test once, so I don't think there's a problem here. If something weird is happening, let me know and I'll dig into the code, but it should be fine.

I'm dumb - I'd completely failed to realise it's being run twice, once in the user's code and again in the tests. You're quite right and @moT01's PR fixes that.

Challenge: https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/regular-expressions/match-anything-with-wildcard-period

Fails with:

let exampleStr = "Let's have fun with regular expressions!";
let unRegex = /.un/gi; // Change this line
let result = unRegex.test(exampleStr);

Passes with:

let exampleStr = "Let's have fun with regular expressions!";
let unRegex = /.un/i; // Change this line
let result = unRegex.test(exampleStr);

The example/seed code moves lastIndex to 14.

let exampleStr = "Let's have fun with regular expressions!";
let unRegex = /.un/gi; // Change this line
let result = unRegex.test(exampleStr);
console.log(unRegex.lastIndex) // 14

I guess one easy option would be to change the example string to something like "_Fun with regular expressions!_", that should let all the tests pass and accept the global flag.

The problem is if the camper uses a different string to test the regex it may fail. So we might just have to reset lastIndex before running the tests.

I assumed it would be the exact same fix as what Tom did:

myRegex.lastIndex = 0;

@lasjorg yep, that's what I concluded.

@Sky020 I think we can apply Tom's fix in js-teardown, rather than modifying the tests. Either works, but that should be more concise.

Was this page helpful?
0 / 5 - 0 ratings