Repository: char0n/ramda-adjunct
Pull request #1128 (2019-10-20 07:34:22)

feat(function): add firstP alias for anyP
Closes https://github.com/char0n/ramda-adjunct/issues/815




Patch:
diff --git a/src/index.js b/src/index.js
index a3dc558547..c84f9b0412 100644
--- a/src/index.js
+++ b/src/index.js
@@ -109,6 +109,7 @@ export { default as sequencing } from './seq';
 export { default as dispatch } from './dispatch';
 export { default as async } from './async';
 export { default as anyP } from './anyP';
+export { default as firstP } from './anyP'; // alias of anyP
 // List
 export { default as mapIndexed } from './mapIndexed';
 export { default as reduceIndexed } from './reduceIndexed';
@@ -192,5 +193,7 @@ export { default as subtractNum } from './subtractNum';
 // String
 export { default as replaceAll } from './replaceAll';
 export { default as escapeRegExp } from './escapeRegExp';
+export { default as trimStart } from './trimStart';
+export { default as trimLeft } from './trimStart'; // alias of trimStart
 // Types
 export { default as Identity } from './fantasy-land/Identity';
diff --git a/src/internal/polyfills/String.trimStart.js b/src/internal/polyfills/String.trimStart.js
new file mode 100644
index 0000000000..0875eee2de
--- /dev/null
+++ b/src/internal/polyfills/String.trimStart.js
@@ -0,0 +1,5 @@
+import { replace } from 'ramda';
+
+const trimStart = replace(/^\s+/, '');
+
+export default trimStart;
diff --git a/src/trimStart.js b/src/trimStart.js
new file mode 100644
index 0000000000..a249bc9c38
--- /dev/null
+++ b/src/trimStart.js
@@ -0,0 +1,29 @@
+import { invoker } from 'ramda';
+
+import polyfill from './internal/polyfills/String.trimStart';
+import isFunction from './isFunction';
+
+export const trimStartPolyfill = polyfill;
+
+export const trimStartInvoker = invoker(0, 'trimStart');
+
+/**
+ * Removes whitespace from the beginning of a string.
+ *
+ * @func trimStart
+ * @memberOf RA
+ * @since {@link https://char0n.github.io/ramda-adjunct/2.22.0|v2.22.0}
+ * @category String
+ * @sig String -> String
+ * @param {string} value String value to have the whitespace removed from the beginning
+ * @return {string} A new string representing the calling string stripped of whitespace from its beginning (left end).
+ * @example
+ *
+ * RA.trimStart('  abc'); //=> 'abc'
+ */
+
+const trimStart = isFunction(String.prototype.trimStart)
+  ? trimStartInvoker
+  : trimStartPolyfill;
+
+export default trimStart;
diff --git a/types/index.d.ts b/types/index.d.ts
index 3498f901f6..7bee4710a1 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -847,6 +847,7 @@ declare namespace RamdaAdjunct {
          * or rejected with an array of rejection reasons if all of the given promises are rejected.
          */
         anyP<T>(iterable: Iterable<T>): Promise<T>;
+        firstP<T>(iterable: Iterable<T>): Promise<T>; // alias
 
         /**
          * Composable shortcut for `Promise.resolve`.
@@ -1241,6 +1242,12 @@ declare namespace RamdaAdjunct {
          * Returns true if all items in the list are unique. `R.equals` is used to determine equality.
          */
         allUnique<T>(list: T[]): boolean;
+
+        /**
+         * Removes whitespace from the beginning of a string
+         */
+        trimStart(value: string): string;
+        trimLeft(value: string): string;
     }
 }
 


Test patch:
diff --git a/test/anyP.js b/test/anyP.js
index f21c2ef4f7..cfff56dc58 100644
--- a/test/anyP.js
+++ b/test/anyP.js
@@ -189,3 +189,9 @@ describe('anyP', function() {
     });
   });
 });
+
+describe('firstP', function() {
+  it('should be alias for anyP', function() {
+    assert.isTrue(RA.firstP === RA.anyP);
+  });
+});
diff --git a/test/trimStart.js b/test/trimStart.js
new file mode 100644
index 0000000000..7f5233a788
--- /dev/null
+++ b/test/trimStart.js
@@ -0,0 +1,119 @@
+import * as R from 'ramda';
+
+import * as RA from '../src';
+import { trimStartInvoker, trimStartPolyfill } from '../src/trimStart';
+import eq from './shared/eq';
+
+describe('trimStart', function() {
+  specify(
+    'should remove whitespace from the beginning of a string',
+    function() {
+      eq(RA.trimStart('  abc'), 'abc');
+    }
+  );
+
+  specify(
+    'should not remove whitespace from the rest of the string',
+    function() {
+      eq(RA.trimStart('a b c '), 'a b c ');
+    }
+  );
+
+  context('given an empty string', function() {
+    specify('should return an empty string', function() {
+      eq(RA.trimStart(''), '');
+    });
+  });
+
+  context('given an string with whitespaces only', function() {
+    specify('should return an empty string', function() {
+      eq(RA.trimStart('   '), '');
+    });
+  });
+
+  specify('should support placeholder to specify "gaps"', function() {
+    const trimStart = RA.trimStart(R.__);
+
+    eq(trimStart('  abc'), 'abc');
+  });
+
+  context('trimStartInvoker', function() {
+    beforeEach(function() {
+      if (RA.isNotFunction(String.prototype.trimStart)) {
+        this.skip();
+      }
+    });
+
+    specify(
+      'should remove whitespace from the beginning of a string',
+      function() {
+        eq(trimStartInvoker('  abc'), 'abc');
+      }
+    );
+
+    specify(
+      'should not remove whitespace from the rest of the string',
+      function() {
+        eq(trimStartInvoker('a b c '), 'a b c ');
+      }
+    );
+
+    context('given an empty string', function() {
+      specify('should return an empty string', function() {
+        eq(trimStartInvoker(''), '');
+      });
+    });
+
+    context('given an string with whitespaces only', function() {
+      specify('should return an empty string', function() {
+        eq(trimStartInvoker('   '), '');
+      });
+    });
+
+    specify('should support placeholder to specify "gaps"', function() {
+      const trimStart = trimStartInvoker(R.__);
+
+      eq(trimStart('  abc'), 'abc');
+    });
+  });
+
+  context('trimStartPolyfill', function() {
+    specify(
+      'should remove whitespace from the beginning of a string',
+      function() {
+        eq(trimStartPolyfill('  abc'), 'abc');
+      }
+    );
+
+    specify(
+      'should not remove whitespace from the rest of the string',
+      function() {
+        eq(trimStartPolyfill('a b c '), 'a b c ');
+      }
+    );
+
+    context('given an empty string', function() {
+      specify('should return an empty string', function() {
+        eq(trimStartPolyfill(''), '');
+      });
+    });
+
+    context('given an string with whitespaces only', function() {
+      specify('should return an empty string', function() {
+        eq(trimStartPolyfill('   '), '');
+      });
+    });
+
+    specify('should support placeholder to specify "gaps"', function() {
+      const trimStart = trimStartPolyfill(R.__);
+
+      eq(trimStart('  abc'), 'abc');
+    });
+  });
+});
+
+describe('trimLeft', function() {
+  it('should be alias of trimStart', function() {
+    eq(RA.trimLeft === RA.trimStart, true);
+  });
+});
diff --git a/types/test/anyP.ts b/types/test/anyP.ts
index 73d289df86..94227b6409 100644
--- a/types/test/anyP.ts
+++ b/types/test/anyP.ts
@@ -10,3 +10,13 @@ RA.anyP(customIterable); // $ExpectType Promise<number>
 
 RA.anyP({}); // $ExpectError
 RA.anyP(1); // $ExpectError
+
+// alias
+RA.firstP([1, 2]); // $ExpectType Promise<number>
+RA.firstP(['a', 'b']); // $ExpectType Promise<string>
+RA.firstP([1, 'a']); // $ExpectType Promise<string | number>
+RA.firstP([]); // $ExpectType Promise<never>
+RA.firstP(customIterable); // $ExpectType Promise<number>
+
+RA.firstP({}); // $ExpectError
+RA.firstP(1); // $ExpectError
diff --git a/types/test/trimStart.ts b/types/test/trimStart.ts
new file mode 100644
index 0000000000..2c196e411e
--- /dev/null
+++ b/types/test/trimStart.ts
@@ -0,0 +1,20 @@
+import * as RA from 'ramda-adjunct';
+
+RA.trimStart('abc'); // $ExpectType string
+RA.trimStart(''); // $ExpectType string
+
+RA.trimStart(1); // $ExpectError
+RA.trimStart({}); // $ExpectError
+RA.trimStart(null); // $ExpectError
+RA.trimStart(undefined); // $ExpectError
+RA.trimStart([]); // $ExpectError
+
+// alias
+RA.trimLeft('abc'); // $ExpectType string
+RA.trimLeft(''); // $ExpectType string
+
+RA.trimLeft(1); // $ExpectError
+RA.trimLeft({}); // $ExpectError
+RA.trimLeft(null); // $ExpectError
+RA.trimLeft(undefined); // $ExpectError
+RA.trimLeft([]); // $ExpectError