Repository: dubzzz/fast-check
Pull request #1798 (2021-04-26 19:25:00)

🚚 Move char arbitraries into /arbitrary
<!-- Why is this PR for? -->
<!-- Describe the reason why you opened this PR or give a link towards the associated issue. -->

## In a nutshell

❌ New feature
❌ Fix an issue
❌ Documentation improvement
✔️ Other: *please explain*

(✔️: yes, ❌: no)

## Potential impacts

None

codesandbox[bot]: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/dubzzz/fast-check/pr/1798/builds/124043) or the icon next to each commit SHA.

Latest deployment of this branch, based on commit c58341693c584136fc9340c4565ff6e8ccd0d261:

|Sandbox| Source |
|--|--|
|[Vanilla](https://codesandbox.io/s/vanilla-jcf4n)| Configuration |
|[fast-check-examples](https://codesandbox.io/s/fast-check-examples-d8rho)| Configuration |


Patch:
diff --git a/src/arbitrary/_internals/builders/CharacterArbitraryBuilder.ts b/src/arbitrary/_internals/builders/CharacterArbitraryBuilder.ts
new file mode 100644
index 00000000..98ca0263
--- /dev/null
+++ b/src/arbitrary/_internals/builders/CharacterArbitraryBuilder.ts
@@ -0,0 +1,7 @@
+import { Arbitrary } from '../../../check/arbitrary/definition/Arbitrary';
+import { integer } from '../../integer';
+
+/** @internal */
+export function buildCharacterArbitrary(min: number, max: number, mapToCode: (v: number) => number): Arbitrary<string> {
+  return integer(min, max).map((n) => String.fromCodePoint(mapToCode(n)));
+}
diff --git a/src/arbitrary/_internals/mappers/PreferPrintable.ts b/src/arbitrary/_internals/mappers/PreferPrintable.ts
new file mode 100644
index 00000000..9d721c96
--- /dev/null
+++ b/src/arbitrary/_internals/mappers/PreferPrintable.ts
@@ -0,0 +1,6 @@
+/** @internal */
+export function preferPrintableMapper(v: number): number {
+  if (v < 95) return v + 0x20; // 0x20-0x7e
+  if (v <= 0x7e) return v - 95;
+  return v;
+}
diff --git a/src/arbitrary/ascii.ts b/src/arbitrary/ascii.ts
new file mode 100644
index 00000000..5ff7384a
--- /dev/null
+++ b/src/arbitrary/ascii.ts
@@ -0,0 +1,12 @@
+import { Arbitrary } from '../check/arbitrary/definition/Arbitrary';
+import { buildCharacterArbitrary } from './_internals/builders/CharacterArbitraryBuilder';
+import { preferPrintableMapper } from './_internals/mappers/PreferPrintable';
+
+/**
+ * For single ascii characters - char code between 0x00 (included) and 0x7f (included)
+ * @remarks Since 0.0.1
+ * @public
+ */
+export function ascii(): Arbitrary<string> {
+  return buildCharacterArbitrary(0x00, 0x7f, preferPrintableMapper);
+}
diff --git a/src/arbitrary/base64.ts b/src/arbitrary/base64.ts
new file mode 100644
index 00000000..9408cc6f
--- /dev/null
+++ b/src/arbitrary/base64.ts
@@ -0,0 +1,19 @@
+import { Arbitrary } from '../check/arbitrary/definition/Arbitrary';
+import { buildCharacterArbitrary } from './_internals/builders/CharacterArbitraryBuilder';
+
+/** @internal */
+function base64Mapper(v: number) {
+  if (v < 26) return v + 65; // A-Z
+  if (v < 52) return v + 97 - 26; // a-z
+  if (v < 62) return v + 48 - 52; // 0-9
+  return v === 62 ? 43 : 47; // +/
+}
+
+/**
+ * For single base64 characters - A-Z, a-z, 0-9, + or /
+ * @remarks Since 0.0.1
+ * @public
+ */
+export function base64(): Arbitrary<string> {
+  return buildCharacterArbitrary(0, 63, base64Mapper);
+}
diff --git a/src/arbitrary/char.ts b/src/arbitrary/char.ts
new file mode 100644
index 00000000..c7800aa0
--- /dev/null
+++ b/src/arbitrary/char.ts
@@ -0,0 +1,20 @@
+import { Arbitrary } from '../check/arbitrary/definition/Arbitrary';
+import { buildCharacterArbitrary } from './_internals/builders/CharacterArbitraryBuilder';
+
+/** @internal */
+function identity(v: number) {
+  return v;
+}
+
+/**
+ * For single printable ascii characters - char code between 0x20 (included) and 0x7e (included)
+ *
+ * {@link https://www.ascii-code.com/}
+ *
+ * @remarks Since 0.0.1
+ * @public
+ */
+export function char(): Arbitrary<string> {
+  // Only printable characters: https://www.ascii-code.com/
+  return buildCharacterArbitrary(0x20, 0x7e, identity);
+}
diff --git a/src/arbitrary/char16bits.ts b/src/arbitrary/char16bits.ts
new file mode 100644
index 00000000..64a5f4c3
--- /dev/null
+++ b/src/arbitrary/char16bits.ts
@@ -0,0 +1,18 @@
+import { Arbitrary } from '../check/arbitrary/definition/Arbitrary';
+import { buildCharacterArbitrary } from './_internals/builders/CharacterArbitraryBuilder';
+import { preferPrintableMapper } from './_internals/mappers/PreferPrintable';
+
+/**
+ * For single characters - all values in 0x0000-0xffff can be generated
+ *
+ * WARNING:
+ *
+ * Some generated characters might appear invalid regarding UCS-2 and UTF-16 encoding.
+ * Indeed values within 0xd800 and 0xdfff constitute surrogate pair characters and are illegal without their paired character.
+ *
+ * @remarks Since 0.0.11
+ * @public
+ */
+export function char16bits(): Arbitrary<string> {
+  return buildCharacterArbitrary(0x0000, 0xffff, preferPrintableMapper);
+}
diff --git a/src/arbitrary/fullUnicode.ts b/src/arbitrary/fullUnicode.ts
new file mode 100644
index 00000000..614308c8
--- /dev/null
+++ b/src/arbitrary/fullUnicode.ts
@@ -0,0 +1,31 @@
+import { Arbitrary } from '../check/arbitrary/definition/Arbitrary';
+import { buildCharacterArbitrary } from './_internals/builders/CharacterArbitraryBuilder';
+import { preferPrintableMapper } from './_internals/mappers/PreferPrintable';
+
+// Characters in the range: U+D800 to U+DFFF
+// are called 'surrogate pairs', they cannot be defined alone and come by pairs
+// JavaScript function 'fromCodePoint' can handle those
+// This unicode builder is able to produce a subset of UTF-16 characters called UCS-2
+// You can refer to 'fromCharCode' documentation for more details
+/** @internal */
+const gapSize = 0xdfff + 1 - 0xd800;
+
+/** @internal */
+function unicodeMapper(v: number) {
+  if (v < 0xd800) return preferPrintableMapper(v);
+  return v + gapSize;
+}
+
+/**
+ * For single unicode characters - any of the code points defined in the unicode standard
+ *
+ * WARNING: Generated values can have a length greater than 1.
+ *
+ * {@link https://tc39.github.io/ecma262/#sec-utf16encoding}
+ *
+ * @remarks Since 0.0.11
+ * @public
+ */
+export function fullUnicode(): Arbitrary<string> {
+  return buildCharacterArbitrary(0x0000, 0x10ffff - gapSize, unicodeMapper);
+}
diff --git a/src/arbitrary/hexa.ts b/src/arbitrary/hexa.ts
new file mode 100644
index 00000000..e7ed15eb
--- /dev/null
+++ b/src/arbitrary/hexa.ts
@@ -0,0 +1,18 @@
+import { Arbitrary } from '../check/arbitrary/definition/Arbitrary';
+import { buildCharacterArbitrary } from './_internals/builders/CharacterArbitraryBuilder';
+
+/** @internal */
+function hexaMapper(v: number): number {
+  return v < 10
+    ? v + 48 // 0-9
+    : v + 97 - 10; // a-f
+}
+
+/**
+ * For single hexadecimal characters - 0-9 or a-f
+ * @remarks Since 0.0.1
+ * @public
+ */
+export function hexa(): Arbitrary<string> {
+  return buildCharacterArbitrary(0, 15, hexaMapper);
+}
diff --git a/src/arbitrary/unicode.ts b/src/arbitrary/unicode.ts
new file mode 100644
index 00000000..2fe8e479
--- /dev/null
+++ b/src/arbitrary/unicode.ts
@@ -0,0 +1,26 @@
+import { Arbitrary } from '../check/arbitrary/definition/Arbitrary';
+import { buildCharacterArbitrary } from './_internals/builders/CharacterArbitraryBuilder';
+import { preferPrintableMapper } from './_internals/mappers/PreferPrintable';
+
+// Characters in the range: U+D800 to U+DFFF
+// are called 'surrogate pairs', they cannot be defined alone and come by pairs
+// JavaScript function 'fromCodePoint' can handle those
+// This unicode builder is able to produce a subset of UTF-16 characters called UCS-2
+// You can refer to 'fromCharCode' documentation for more details
+/** @internal */
+const gapSize = 0xdfff + 1 - 0xd800;
+
+/** @internal */
+function unicodeMapper(v: number) {
+  if (v < 0xd800) return preferPrintableMapper(v);
+  return v + gapSize;
+}
+
+/**
+ * For single unicode characters defined in the BMP plan - char code between 0x0000 (included) and 0xffff (included) and without the range 0xd800 to 0xdfff (surrogate pair characters)
+ * @remarks Since 0.0.11
+ * @public
+ */
+export function unicode(): Arbitrary<string> {
+  return buildCharacterArbitrary(0x0000, 0xffff - gapSize, unicodeMapper);
+}
diff --git a/src/check/arbitrary/CharacterArbitrary.ts b/src/check/arbitrary/CharacterArbitrary.ts
deleted file mode 100644
index 1e8fee1e..00000000
--- a/src/check/arbitrary/CharacterArbitrary.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { Arbitrary } from './definition/Arbitrary';
-import { integer } from '../../arbitrary/integer';
-
-/** @internal */
-function CharacterArbitrary(min: number, max: number, mapToCode: (v: number) => number) {
-  return integer(min, max).map((n) => String.fromCodePoint(mapToCode(n)));
-}
-
-/** @internal */
-const preferPrintableMapper = (v: number): number => {
-  if (v < 95) return v + 0x20; // 0x20-0x7e
-  if (v <= 0x7e) return v - 95;
-  return v;
-};
-
-/**
- * For single printable ascii characters - char code between 0x20 (included) and 0x7e (included)
- *
- * {@link https://www.ascii-code.com/}
- *
- * @remarks Since 0.0.1
- * @public
- */
-function char(): Arbitrary<string> {
-  // Only printable characters: https://www.ascii-code.com/
-  return CharacterArbitrary(0x20, 0x7e, (v) => v);
-}
-
-/**
- * For single hexadecimal characters - 0-9 or a-f
- * @remarks Since 0.0.1
- * @public
- */
-function hexa(): Arbitrary<string> {
-  function mapper(v: number) {
-    return v < 10
-      ? v + 48 // 0-9
-      : v + 97 - 10; // a-f
-  }
-  return CharacterArbitrary(0, 15, mapper);
-}
-
-/**
- * For single base64 characters - A-Z, a-z, 0-9, + or /
- * @remarks Since 0.0.1
- * @public
- */
-function base64(): Arbitrary<string> {
-  function mapper(v: number) {
-    if (v < 26) return v + 65; // A-Z
-    if (v < 52) return v + 97 - 26; // a-z
-    if (v < 62) return v + 48 - 52; // 0-9
-    return v === 62 ? 43 : 47; // +/
-  }
-  return CharacterArbitrary(0, 63, mapper);
-}
-
-/**
- * For single ascii characters - char code between 0x00 (included) and 0x7f (included)
- * @remarks Since 0.0.1
- * @public
- */
-function ascii(): Arbitrary<string> {
-  return CharacterArbitrary(0x00, 0x7f, preferPrintableMapper);
-}
-
-/**
- * For single characters - all values in 0x0000-0xffff can be generated
- *
- * WARNING:
- *
- * Some generated characters might appear invalid regarding UCS-2 and UTF-16 encoding.
- * Indeed values within 0xd800 and 0xdfff constitute surrogate pair characters and are illegal without their paired character.
- *
- * @remarks Since 0.0.11
- * @public
- */
-function char16bits(): Arbitrary<string> {
-  return CharacterArbitrary(0x0000, 0xffff, preferPrintableMapper);
-}
-
-/**
- * For single unicode characters defined in the BMP plan - char code between 0x0000 (included) and 0xffff (included) and without the range 0xd800 to 0xdfff (surrogate pair characters)
- * @remarks Since 0.0.11
- * @public
- */
-function unicode(): Arbitrary<string> {
-  // Characters in the range: U+D800 to U+DFFF
-  // are called 'surrogate pairs', they cannot be defined alone and come by pairs
-  // JavaScript function 'fromCodePoint' can handle those
-  // This unicode builder is able to produce a subset of UTF-16 characters called UCS-2
-  // You can refer to 'fromCharCode' documentation for more details
-  const gapSize = 0xdfff + 1 - 0xd800;
-  function mapping(v: number) {
-    if (v < 0xd800) return preferPrintableMapper(v);
-    return v + gapSize;
-  }
-  return CharacterArbitrary(0x0000, 0xffff - gapSize, mapping);
-}
-
-/**
- * For single unicode characters - any of the code points defined in the unicode standard
- *
- * WARNING: Generated values can have a length greater than 1.
- *
- * {@link https://tc39.github.io/ecma262/#sec-utf16encoding}
- *
- * @remarks Since 0.0.11
- * @public
- */
-function fullUnicode(): Arbitrary<string> {
-  // Be aware that 'characters' can have a length greater than 1
-  // More details on: https://tc39.github.io/ecma262/#sec-utf16encoding
-  // This unicode builder is able to produce all the UTF-16 characters
-  // It only produces valid UTF-16 code points
-  const gapSize = 0xdfff + 1 - 0xd800;
-  function mapping(v: number) {
-    if (v < 0xd800) return preferPrintableMapper(v);
-    return v + gapSize;
-  }
-  return CharacterArbitrary(0x0000, 0x10ffff - gapSize, mapping);
-}
-
-export { char, ascii, char16bits, unicode, fullUnicode, hexa, base64 };
diff --git a/src/check/arbitrary/StringArbitrary.ts b/src/check/arbitrary/StringArbitrary.ts
index bd484050..c56e9983 100644
--- a/src/check/arbitrary/StringArbitrary.ts
+++ b/src/check/arbitrary/StringArbitrary.ts
@@ -1,6 +1,12 @@
 import { array } from '../../arbitrary/array';
 import { maxLengthFromMinLength } from '../../arbitrary/_internals/helpers/MaxLengthFromMinLength';
-import { ascii, base64, char, char16bits, fullUnicode, hexa, unicode } from './CharacterArbitrary';
+import { ascii } from '../../arbitrary/ascii';
+import { base64 } from '../../arbitrary/base64';
+import { char } from '../../arbitrary/char';
+import { char16bits } from '../../arbitrary/char16bits';
+import { fullUnicode } from '../../arbitrary/fullUnicode';
+import { hexa } from '../../arbitrary/hexa';
+import { unicode } from '../../arbitrary/unicode';
 import { Arbitrary } from './definition/Arbitrary';
 
 /**
diff --git a/src/check/arbitrary/helpers/SpecificCharacterRange.ts b/src/check/arbitrary/helpers/SpecificCharacterRange.ts
index 64924632..3a23a03b 100644
--- a/src/check/arbitrary/helpers/SpecificCharacterRange.ts
+++ b/src/check/arbitrary/helpers/SpecificCharacterRange.ts
@@ -1,4 +1,4 @@
-import { fullUnicode } from '../CharacterArbitrary';
+import { fullUnicode } from '../../../arbitrary/fullUnicode';
 import { Arbitrary } from '../definition/Arbitrary';
 import { frequency } from '../../../arbitrary/frequency';
 import { mapToConstant } from '../MapToConstantArbitrary';
diff --git a/src/fast-check-default.ts b/src/fast-check-default.ts
index b5c93874..21c06e9b 100644
--- a/src/fast-check-default.ts
+++ b/src/fast-check-default.ts
@@ -26,7 +26,13 @@ import { bigUint, BigUintConstraints } from './arbitrary/bigUint';
 import { bigUintN } from './arbitrary/bigUintN';
 import { boolean } from './check/arbitrary/BooleanArbitrary';
 import { falsy, FalsyContraints, FalsyValue } from './arbitrary/falsy';
-import { ascii, base64, char, char16bits, fullUnicode, hexa, unicode } from './check/arbitrary/CharacterArbitrary';
+import { ascii } from './arbitrary/ascii';
+import { base64 } from './arbitrary/base64';
+import { char } from './arbitrary/char';
+import { char16bits } from './arbitrary/char16bits';
+import { fullUnicode } from './arbitrary/fullUnicode';
+import { hexa } from './arbitrary/hexa';
+import { unicode } from './arbitrary/unicode';
 import { clonedConstant } from './arbitrary/clonedConstant';
 import { constant } from './arbitrary/constant';
 import { constantFrom } from './arbitrary/constantFrom';


Test patch:
diff --git a/test/unit/check/arbitrary/CharacterArbitrary.spec.ts b/test/unit/arbitrary/CharacterArbitrary.spec.ts
similarity index 86%
rename from test/unit/check/arbitrary/CharacterArbitrary.spec.ts
rename to test/unit/arbitrary/CharacterArbitrary.spec.ts
index 722f5fd1..cc3d374c 100644
--- a/test/unit/check/arbitrary/CharacterArbitrary.spec.ts
+++ b/test/unit/arbitrary/CharacterArbitrary.spec.ts
@@ -1,14 +1,12 @@
-import {
-  char,
-  ascii,
-  char16bits,
-  unicode,
-  hexa,
-  base64,
-  fullUnicode,
-} from '../../../../src/check/arbitrary/CharacterArbitrary';
+import { char } from '../../../src/arbitrary/char';
+import { ascii } from '../../../src/arbitrary/ascii';
+import { char16bits } from '../../../src/arbitrary/char16bits';
+import { unicode } from '../../../src/arbitrary/unicode';
+import { hexa } from '../../../src/arbitrary/hexa';
+import { base64 } from '../../../src/arbitrary/base64';
+import { fullUnicode } from '../../../src/arbitrary/fullUnicode';
 
-import * as genericHelper from './generic/GenericArbitraryHelper';
+import * as genericHelper from '../check/arbitrary/generic/GenericArbitraryHelper';
 
 const remapCharToIndex = (c: string): number => {
   const cp = c.codePointAt(0)!;
diff --git a/test/unit/check/runner/Runner.spec.ts b/test/unit/check/runner/Runner.spec.ts
index da41314d..9447febf 100644
--- a/test/unit/check/runner/Runner.spec.ts
+++ b/test/unit/check/runner/Runner.spec.ts
@@ -1,7 +1,7 @@
 import * as fc from '../../../../lib/fast-check';
 
 import { Shrinkable } from '../../../../src/check/arbitrary/definition/Shrinkable';
-import { char } from '../../../../src/check/arbitrary/CharacterArbitrary';
+import { char } from '../../../../src/arbitrary/char';
 import { IRawProperty } from '../../../../src/check/property/IRawProperty';
 import { check, assert as rAssert } from '../../../../src/check/runner/Runner';
 import { Random } from '../../../../src/random/generator/Random';