function booleanTests(feature) { const windowURL = 'resources/close-self.html'; // Tests for how windows features are tokenized into 'name', 'value' // window features separators are ASCII whitespace, '=' and ',' const featureUpper = feature.toUpperCase(), featureSplitBegin = feature.slice(0, 2), featureSplitEnd = feature.slice(2), featureMixedCase = featureSplitBegin.toUpperCase() + featureSplitEnd; featureMixedCase2 = featureSplitBegin + featureSplitEnd.toUpperCase(); test (t => { // Tokenizing `name`: initial window features separators are ignored // Each of these variants should tokenize to (`${feature}`, '') [ ` ${feature}`, `=${feature}`, `,,${feature}`, `,=, ${feature}`, `\n=${feature}=`, `\t${feature}`, `\r,,,=${feature}`, `\u000C${feature}` ].forEach(variant => { const win = window.open(windowURL, "", variant); assert_equals(win, null, `"${variant}" should activate feature "${feature}"`); }); }, `Tokenization of "${feature}" should skip window features separators before feature`); test (t => { // Tokenizing `name`: lowercase conversion // Each of these variants should tokenize as feature (`${feature}`, '') // except where indicated // Note also that `value` is lowercased during tokenization [ `${featureUpper}`, `${featureMixedCase}`, ` ${featureMixedCase2}`, `=${featureUpper}`, `${featureUpper}=1`, `${featureUpper}=1`, `${featureUpper}=yes`, `${feature}=YES`, ].forEach(variant => { const win = window.open(windowURL, '', variant); assert_equals(win, null, `"${variant}" should activate feature "${feature}"`); }); }, `Feature "${feature}" should be converted to ASCII lowercase`); test (t => { // After `name` has been collected, ignore any window features separators until '=' // except ',' OR a non-window-features-separator — break in those cases // i.e. ignore whitespace until '=' unless a ',' is encountered first // Each of these variants should tokenize as feature ('noopener', '') [ `${feature}`, ` ${feature}\r`, `${feature}\n =`, `${feature},`, `${feature} =,`, `, ${feature} =`, `${feature},=`, `${feature} foo`, `foo ${feature}=1`, `foo=\u000Cbar\u000C${feature}` ].forEach(variant => { const win = window.open(windowURL, '', variant); assert_equals(win, null, `"${variant}" should activate feature "${feature}"`); }); }, `After "${feature}", tokenization should skip window features separators that are not "=" or ","`); test (t => { // After initial '=', tokenizing should ignore all separators except ',' // before collecting `value` // Each of these variants should tokenize as feature ('noopener', '') // Except where indicated [ `${feature}= yes`, `${feature}==,`, `${feature}=\n ,`, `${feature} = \t ,`, `${feature}\n=\r 1,`, `${feature}=,yes`, `${feature}= yes=,`, `${feature} = \u000Cyes` ].forEach(variant => { const win = window.open(windowURL, '', variant); assert_equals(win, null, `"${variant}" should activate feature "${feature}"`); }); }, `Tokenizing "${feature}" should ignore window feature separators except "," after initial "=" and before value`); test (t => { // Tokenizing `value` should collect any non-separator code points until first separator [ `${feature}=1`, `${feature}=yes`, `${feature} = yes ,`, `${feature}=\nyes ,`, `${feature}=yes yes`, `${feature}=yes\ts`, `${feature}==`, `${feature}=1\n,`, `==${feature}===`, `${feature}==\u000C` ].forEach(variant => { const win = window.open(windowURL, '', variant); assert_equals(win, null, `"${variant}" should set "${feature}"`); }); }, `Tokenizing "${feature}" should read characters until first window feature separator as \`value\``); test (t => { [ `${feature}=1`, `${feature}=2`, `${feature}=12345`, `${feature}=1.5`, `${feature}=-1`, ].forEach(variant => { const win = window.open(windowURL, '', variant); assert_equals(win, null, `"${variant}" should activate feature "${feature}"`); }); }, 'Integer values other than 0 should activate the feature'); test (t => { [ `${feature}=0`, `${feature}=0.5`, `${feature}=error`, ].forEach(variant => { const win = window.open(windowURL, '', variant); assert_not_equals(win, null, `"${variant}" should NOT activate feature "${feature}"`); }); }, `Integer value of 0 should not activate "${feature}"`); test (t => { [ `-${feature}`, `${featureUpper}RRR`, `${featureMixedCase}R`, `${featureSplitBegin}_${featureSplitEnd}`, ` ${featureSplitBegin} ${featureSplitEnd}`, `${featureSplitBegin}\n${featureSplitEnd}`, `${featureSplitBegin},${featureSplitEnd}`, `\0${feature}`, `${feature}\u0000=yes`, `foo=\u000C${feature}` ].forEach(variant => { const win = window.open(windowURL, '', variant); assert_not_equals(win, null, `"${variant}" should NOT activate feature "${feature}"`); }); }, `Invalid feature names should not tokenize as "${feature}"`); }