const fc = require('fast-check');
const testIt = (arb) => console.log(fc.sample(arb, 5));
const regexCharacterArb = fc.fullUnicode().filter(c => !'^$\.*+?()[]{}|'.includes(c));
//testIt(regexCharacterArb);
const hexaNotationArb = fc.nat(255).map(n => '\\x' + Number(n).toString(16).padStart(2, '0'));
//testIt(hexaNotationArb);
const unicodeNotationArb = fc.oneof(
fc.unicode().map(c => '\\u' + Number(c.codePointAt(0)).toString(16).padStart(4, '0')),
fc.fullUnicode().map(c => '\\u{' + Number(c.codePointAt(0)).toString(16).padStart(4, '0') + '}'));
//testIt(unicodeNotationArb);
const controlEscapeArb = fc.constantFrom('\\f','\\n','\\r','\\t','\\v');
//testIt(controlEscapeArb);
const controlLetterArb = fc.constantFrom(
'\\cA','\\cB','\\cC','\\cD','\\cE','\\cF',
'\\cG','\\cH','\\cI','\\cJ','\\cK','\\cL',
'\\cM','\\cN','\\cO','\\cP','\\cQ','\\cR',
'\\cS','\\cT','\\cU','\\cV','\\cW','\\cX',
'\\cY','\\cZ');
//testIt(controlLetterArb);
const characterClassEscapeArb = fc.constantFrom('\\d','\\D','\\s','\\S','\\w','\\W','.'); // and .
//testIt(characterClassEscapeArb);
const escapedSyntaxCharacterArb = fc.constantFrom(
'\\^','\\#x27;,'\\\\','\\.','\\*','\\+','\\?',
'\\(','\\)','\\[','\\]','\\{','\\}','\\|');
//testIt(escapedSyntaxCharacterArb);
const variousOneCharacterArb = fc.oneof(regexCharacterArb, characterClassEscapeArb, escapedSyntaxCharacterArb, hexaNotationArb, unicodeNotationArb, controlEscapeArb, controlLetterArb);
const bracketRegexArb = fc.tuple(
fc.boolean(),
fc.stringOf(fc.oneof(
variousOneCharacterArb.filter(c => c !== '-' && c !== '\\x2d' && c !== '\\u002d' && c !== '\\u{002d}'),
fc.tuple(regexCharacterArb, regexCharacterArb)
.filter(([a, b]) => a.codePointAt(0) !== 0x2d && b.codePointAt(0) !== 0x2d)
.map(([a, b]) => a.codePointAt(0) < b.codePointAt(0) ? [a,b]: [b,a])
.map(([a, b]) => `${a}-${b}`)
)),
fc.boolean()
).map(([startDash, s, endDash]) => `[${startDash?'-':''}${s}${endDash?'-':''}]`)
//testIt(bracketRegexArb);
const noCaptureArb = fc.array(fc.oneof(bracketRegexArb, fc.stringOf(variousOneCharacterArb)))
.map(content => `${content.join('')}`);
//testIt(noCaptureArb);
const braceRegexArb = fc.array(noCaptureArb)
.map(content => `(${content.join('|')})`);
//testIt(braceRegexArb);
const regexArb = fc.array(fc.oneof(braceRegexArb, bracketRegexArb, fc.stringOf(variousOneCharacterArb)))
.map(content => `${content.join('|')}`);
testIt(regexArb);
fc.assert(
fc.property(
regexArb,
pattern => { new RegExp(pattern, 'u'); } // does not crash - ie. valid regex
), {numRuns: 10000}
);