Repository: char0n/ramda-adjunct
Pull request #1141 (2019-10-23 07:34:18)

test(replaceAll): make tests consistent with other string functions
Ref #878



char0n: @js636f FYI just made some consistency cleanup in tests.

Patch:
diff --git a/package-lock.json b/package-lock.json
index 4eda9cdb9a..af3c5dd61e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1772,9 +1772,9 @@
       "dev": true
     },
     "acorn-jsx": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz",
-      "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==",
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
+      "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==",
       "dev": true
     },
     "add-stream": {
@@ -3083,6 +3083,12 @@
         "delayed-stream": "~1.0.0"
       }
     },
+    "command-exists": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz",
+      "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==",
+      "dev": true
+    },
     "commander": {
       "version": "2.19.0",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
@@ -4176,11 +4182,12 @@
       "dev": true
     },
     "dts-critic": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/dts-critic/-/dts-critic-2.0.0.tgz",
-      "integrity": "sha512-oYo69B8NcjUoDhKh8oUl58ljMsgyWnPR0Qf3QKJmKjm5LvkQ21v4SW+QCOleI1Cs0HRN6zEYllvQEORGd45wOQ==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/dts-critic/-/dts-critic-2.2.0.tgz",
+      "integrity": "sha512-QFVMR85VMyqI8zfnboyRGNvkf+NOk+i/13V09Z/M8Kh/WivOId8TIO6q0d3NAmGyRJXP5TjQmxadWmwTFn1HBQ==",
       "dev": true,
       "requires": {
+        "command-exists": "^1.2.8",
         "definitelytyped-header-parser": "^1.2.0",
         "download-file-sync": "^1.0.4",
         "semver": "^6.2.0",
@@ -4206,24 +4213,24 @@
       }
     },
     "dtslint": {
-      "version": "0.9.7",
-      "resolved": "https://registry.npmjs.org/dtslint/-/dtslint-0.9.7.tgz",
-      "integrity": "sha512-dZ6dplgDsXKkN9NNQUYjOVs2kHzesVR+rFQ/PTd9NhQH+tc5a6ipUKF1eGKQqeHSSrSGnDz4mRTIxsiYgVGwJg==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/dtslint/-/dtslint-1.0.2.tgz",
+      "integrity": "sha512-DumNrKbecCJuLgbkCMT2GOBf9GSpArcv+Mbd/xzdj5muSHQOpruudeVVEBo0r6veHxrg3g3jCAA2EqnhH1MybQ==",
       "dev": true,
       "requires": {
-        "definitelytyped-header-parser": "^3.7.2",
-        "dts-critic": "^2.0.0",
+        "definitelytyped-header-parser": "3.7.2",
+        "dts-critic": "^2.2.0",
         "fs-extra": "^6.0.1",
         "request": "^2.88.0",
         "strip-json-comments": "^2.0.1",
         "tslint": "5.14.0",
-        "typescript": "=3.7.0-dev.20190912"
+        "typescript": "=3.8.0-dev.20191031"
       },
       "dependencies": {
         "typescript": {
-          "version": "3.7.0-dev.20190912",
-          "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.0-dev.20190912.tgz",
-          "integrity": "sha512-5rAOCT1CLjQ2nYeKwa6SOnpSW8N+EEFE6WbNOLrzsSyZwYysE1oHCw4SYil3ZsBVtiEmCYnPWck525dOpgUHDg==",
+          "version": "3.8.0-dev.20191031",
+          "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.0-dev.20191031.tgz",
+          "integrity": "sha512-hnIkoA1tdqCoO71ocviQg+ojLPwuZw6IxUtW12hhI+0XCpqNinQOcvUJlak0pVRUKL6vMRjvmhMbE0+uDJp/sA==",
           "dev": true
         }
       }
@@ -4535,9 +4542,9 @@
       }
     },
     "eslint": {
-      "version": "6.5.1",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz",
-      "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==",
+      "version": "6.6.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.6.0.tgz",
+      "integrity": "sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.0.0",
@@ -4547,9 +4554,9 @@
         "debug": "^4.0.1",
         "doctrine": "^3.0.0",
         "eslint-scope": "^5.0.0",
-        "eslint-utils": "^1.4.2",
+        "eslint-utils": "^1.4.3",
         "eslint-visitor-keys": "^1.1.0",
-        "espree": "^6.1.1",
+        "espree": "^6.1.2",
         "esquery": "^1.0.1",
         "esutils": "^2.0.2",
         "file-entry-cache": "^5.0.1",
@@ -4559,7 +4566,7 @@
         "ignore": "^4.0.6",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
-        "inquirer": "^6.4.1",
+        "inquirer": "^7.0.0",
         "is-glob": "^4.0.0",
         "js-yaml": "^3.13.1",
         "json-stable-stringify-without-jsonify": "^1.0.1",
@@ -4687,9 +4694,9 @@
       }
     },
     "eslint-config-prettier": {
-      "version": "6.4.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.4.0.tgz",
-      "integrity": "sha512-YrKucoFdc7SEko5Sxe4r6ixqXPDP1tunGw91POeZTTRKItf/AMFYt/YLEQtZMkR2LVpAVhcAcZgcWpm1oGPW7w==",
+      "version": "6.5.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.5.0.tgz",
+      "integrity": "sha512-cjXp8SbO9VFGW/Z7mbTydqS9to8Z58E5aYhj3e1+Hx7lS9s6gL5ILKNpCqZAFOVYRcSkWPFYljHrEh8QFEK5EQ==",
       "dev": true,
       "requires": {
         "get-stdin": "^6.0.0"
@@ -4784,7 +4791,7 @@
         },
         "pify": {
           "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
           "dev": true
         },
@@ -4821,9 +4828,9 @@
       }
     },
     "eslint-plugin-mocha": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.2.0.tgz",
-      "integrity": "sha512-vE/+tHJVom2BkMOiwkOKcAM5YqGPk3C6gMvQ32DHihKkaXF6vmxtj3UEOg64wP3m8/Zk5V/UmQbFE5nqu1EXSg==",
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.2.1.tgz",
+      "integrity": "sha512-o3Ibhpczi5MjUVpnlnrpC/+oJYGoHKB5m4bQdRnaAOeFCN3HRkqBisQ2/h0hEuCR4lPxyHP1Qzyjpna8MsOdlA==",
       "dev": true,
       "requires": {
         "ramda": "^0.26.1"
@@ -4868,12 +4875,12 @@
       }
     },
     "eslint-utils": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
-      "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+      "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
       "dev": true,
       "requires": {
-        "eslint-visitor-keys": "^1.0.0"
+        "eslint-visitor-keys": "^1.1.0"
       }
     },
     "eslint-visitor-keys": {
@@ -4883,13 +4890,13 @@
       "dev": true
     },
     "espree": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz",
-      "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz",
+      "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==",
       "dev": true,
       "requires": {
-        "acorn": "^7.0.0",
-        "acorn-jsx": "^5.0.2",
+        "acorn": "^7.1.0",
+        "acorn-jsx": "^5.1.0",
         "eslint-visitor-keys": "^1.1.0"
       },
       "dependencies": {
@@ -6414,7 +6421,7 @@
         },
         "camelcase-keys": {
           "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+          "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
           "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
           "dev": true,
           "requires": {
@@ -6449,7 +6456,7 @@
         },
         "load-json-file": {
           "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+          "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
           "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
           "dev": true,
           "requires": {
@@ -6468,7 +6475,7 @@
         },
         "meow": {
           "version": "3.7.0",
-          "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+          "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
           "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
           "dev": true,
           "requires": {
@@ -6521,7 +6528,7 @@
         },
         "pify": {
           "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
           "dev": true
         },
@@ -6662,7 +6669,7 @@
       "dependencies": {
         "pify": {
           "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
           "dev": true
         }
@@ -7081,9 +7088,9 @@
       "dev": true
     },
     "https-proxy-agent": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
-      "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
+      "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
       "dev": true,
       "requires": {
         "agent-base": "^4.3.0",
@@ -7413,26 +7420,35 @@
       "dev": true
     },
     "inquirer": {
-      "version": "6.5.2",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
-      "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz",
+      "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==",
       "dev": true,
       "requires": {
-        "ansi-escapes": "^3.2.0",
+        "ansi-escapes": "^4.2.1",
         "chalk": "^2.4.2",
-        "cli-cursor": "^2.1.0",
+        "cli-cursor": "^3.1.0",
         "cli-width": "^2.0.0",
         "external-editor": "^3.0.3",
-        "figures": "^2.0.0",
-        "lodash": "^4.17.12",
-        "mute-stream": "0.0.7",
+        "figures": "^3.0.0",
+        "lodash": "^4.17.15",
+        "mute-stream": "0.0.8",
         "run-async": "^2.2.0",
         "rxjs": "^6.4.0",
-        "string-width": "^2.1.0",
+        "string-width": "^4.1.0",
         "strip-ansi": "^5.1.0",
         "through": "^2.3.6"
       },
       "dependencies": {
+        "ansi-escapes": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz",
+          "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.5.2"
+          }
+        },
         "ansi-regex": {
           "version": "4.1.0",
           "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
@@ -7450,6 +7466,78 @@
             "supports-color": "^5.3.0"
           }
         },
+        "cli-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+          "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+          "dev": true,
+          "requires": {
+            "restore-cursor": "^3.1.0"
+          }
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+          "dev": true
+        },
+        "figures": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz",
+          "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==",
+          "dev": true,
+          "requires": {
+            "escape-string-regexp": "^1.0.5"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "onetime": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+          "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "restore-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+          "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+          "dev": true,
+          "requires": {
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2"
+          }
+        },
+        "string-width": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz",
+          "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^5.2.0"
+          }
+        },
         "strip-ansi": {
           "version": "5.2.0",
           "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
@@ -7458,6 +7546,12 @@
           "requires": {
             "ansi-regex": "^4.1.0"
           }
+        },
+        "type-fest": {
+          "version": "0.5.2",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz",
+          "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==",
+          "dev": true
         }
       }
     },
@@ -9647,9 +9741,9 @@
       "dev": true
     },
     "mute-stream": {
-      "version": "0.0.7",
-      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
       "dev": true
     },
     "nan": {
@@ -10979,7 +11073,7 @@
       "dependencies": {
         "jsesc": {
           "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
           "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
           "dev": true
         }
@@ -13160,9 +13254,9 @@
       }
     },
     "webpack-cli": {
-      "version": "3.3.9",
-      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.9.tgz",
-      "integrity": "sha512-xwnSxWl8nZtBl/AFJCOn9pG7s5CYUYdZxmmukv+fAHLcBIHM36dImfpQg3WfShZXeArkWlf6QRw24Klcsv8a5A==",
+      "version": "3.3.10",
+      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz",
+      "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==",
       "dev": true,
       "requires": {
         "chalk": "2.4.2",
@@ -13577,9 +13671,9 @@
       },
       "dependencies": {
         "camelcase": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
-          "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
           "dev": true
         },
         "find-up": {
@@ -13602,9 +13696,9 @@
           }
         },
         "p-limit": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
-          "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+          "version": "2.2.1",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
+          "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
           "dev": true,
           "requires": {
             "p-try": "^2.0.0"
@@ -13620,9 +13714,9 @@
           }
         },
         "p-try": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
-          "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
           "dev": true
         },
         "yargs-parser": {
diff --git a/package.json b/package.json
index 4558b35620..35f2cf2b25 100644
--- a/package.json
+++ b/package.json
@@ -144,12 +144,12 @@
     "codecov": "3.6.1",
     "conventional-changelog-cli": "2.0.25",
     "docdash": "git+https://github.com/char0n/docdash.git#534b44382138a55dd8d93642c979e51e46471185",
-    "dtslint": "0.9.7",
-    "eslint": "6.5.1",
+    "dtslint": "=1.0.2",
+    "eslint": "6.6.0",
     "eslint-config-airbnb-base": "=14.0.0",
-    "eslint-config-prettier": "6.4.0",
+    "eslint-config-prettier": "6.5.0",
     "eslint-plugin-import": "2.18.2",
-    "eslint-plugin-mocha": "6.2.0",
+    "eslint-plugin-mocha": "6.2.1",
     "eslint-plugin-prettier": "3.1.1",
     "eslint-plugin-ramda": "2.5.1",
     "fantasy-land": "4.0.0",
@@ -178,7 +178,7 @@
     "tslint": "=5.14.0",
     "typescript": "=3.5.3",
     "webpack": "4.41.2",
-    "webpack-cli": "3.3.9"
+    "webpack-cli": "3.3.10"
   },
   "browserslist": "> 0.25%, ie 10, ie 11, not op_mini all",
   "tonicExampleFilename": "tonicExample.js",
diff --git a/src/index.js b/src/index.js
index 238ced776b..b99ab646ae 100644
--- a/src/index.js
+++ b/src/index.js
@@ -162,6 +162,7 @@ export { default as spreadProp } from './spreadProp';
 export { default as spreadPath } from './spreadPath';
 export { default as flattenProp } from './flattenProp';
 export { default as flattenPath } from './flattenPath';
+export { default as unzipObjWith } from './unzipObjWith';
 // Relation
 export { default as lensEq } from './lensEq';
 export { default as lensNotEq } from './lensNotEq';
@@ -199,5 +200,6 @@ export { default as trimLeft } from './trimStart'; // alias of trimStart
 export { default as trimEnd } from './trimEnd';
 export { default as trimRight } from './trimEnd'; // alias of trimEnd
 export { default as padCharsEnd } from './padCharsEnd';
+export { default as padEnd } from './padEnd';
 // Types
 export { default as Identity } from './fantasy-land/Identity';
diff --git a/src/padEnd.js b/src/padEnd.js
new file mode 100644
index 0000000000..bc31e06974
--- /dev/null
+++ b/src/padEnd.js
@@ -0,0 +1,25 @@
+import padCharsEnd from './padCharsEnd';
+
+/**
+ * The function pads the current string with an empty string
+ * so that the resulting string reaches a given length.
+ * The padding is applied from the end of the current string.
+ *
+ * @func padEnd
+ * @memberOf RA
+ * @since {@link https://char0n.github.io/ramda-adjunct/2.22.0|v2.22.0}
+ * @category String
+ * @sig Number -> String -> String
+ * @param {number} targetLength The length of the resulting string once
+ * the current string has been padded
+ * @param {string} value String value to be padded
+ * @return {string} A new string of the specified length with the pad string
+ * applied at the end of the current string
+ * @see {@link RA.padCharsEnd|padCharsEnd}, {@link RA.padCharsStart|padCharsStart}, {@link RA.padStart|padStart}
+ * @example
+ *
+ * RA.padEnd(3, 'a'); // => 'a  '
+ */
+const padEnd = padCharsEnd(' ');
+
+export default padEnd;
diff --git a/src/unzipObjWith.js b/src/unzipObjWith.js
new file mode 100644
index 0000000000..0741b25d1a
--- /dev/null
+++ b/src/unzipObjWith.js
@@ -0,0 +1,45 @@
+import {
+  apply,
+  curryN,
+  flip,
+  map,
+  pipe,
+  toPairs,
+  transpose,
+  when,
+} from 'ramda';
+
+import lengthEq from './lengthEq';
+
+/**
+ * Creates a new list out of the supplied object by applying the function to each key/value pairing.
+ *
+ * @func unzipObjWith
+ * @memberOf RA
+ * @category Object
+ * @since {@link https://char0n.github.io/ramda-adjunct/2.22.0|v2.22.0}
+ * @sig  (v, k) => [k, v] -> { k: v } -> [[k], [v]]
+ * @param {Function} fn The function to transform each value-key pair
+ * @param {Object} obj Object to unzip
+ * @return {Array} A pair of tw lists: a list of keys and a list of values
+ * @see {@link https://ramdajs.com/docs/#zipObj|zipObj}, {@link RA.zipObjWith|zipObjWith}
+ * @example
+ *
+ * RA.unzipObjWith((v, k) => [`new${k.toUpperCase()}`, 2 * v], { a: 1, b: 2, c: 3 });
+ * //=> [['newA', 'newB', 'newC'], [2, 4, 6]]
+ */
+const unzipObjWith = curryN(2, (fn, obj) =>
+  pipe(
+    toPairs,
+    map(
+      pipe(
+        flip,
+        apply
+      )(fn)
+    ),
+    transpose,
+    when(lengthEq(0), () => [[], []])
+  )(obj)
+);
+
+export default unzipObjWith;
diff --git a/types/index.d.ts b/types/index.d.ts
index 0f1a4d8f7d..191c3f73de 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -820,6 +820,12 @@ declare namespace RamdaAdjunct {
         flattenProp(prop: string | number, obj: object): object;
         flattenProp(prop: string | number): (obj: object) => object;
 
+        /**
+         * Creates a new list out of the supplied object by applying the function to each key/value pairing.
+         */
+        unzipObjWith<T, U, V>(fn: (v: T, k: string) => [U, V], obj: { [k: string]: T }): [U[], V[]];
+        unzipObjWith<T, U, V>(fn: (v: T, k: string) => [U, V]): (obj: { [k: string]: T }) => [U[], V[]];
+
         /**
          * Composable shortcut for `Promise.all`.
          *
@@ -1268,6 +1274,14 @@ declare namespace RamdaAdjunct {
         padCharsEnd(padString: string, targetLength: number, value: string): string;
         padCharsEnd(padString: string, targetLength: number): (value: string) => string;
         padCharsEnd(padString: string): (targetLength: number, value: string) => string;
+
+        /**
+         * The function pads the current string with an empty string
+         * so that the resulting string reaches a given length.
+         * The padding is applied from the end of the current string.
+         */
+        padEnd(targetLength: number, value: string): string;
+        padEnd(targetLength: number): (value: string) => string;
     }
 }
 
diff --git a/types/tslint.json b/types/tslint.json
index e6b68356b5..a41732cd44 100644
--- a/types/tslint.json
+++ b/types/tslint.json
@@ -16,6 +16,7 @@
       "no-import-default-of-export-equals": [false],
       "no-relative-import-in-test": [false],
       "no-unnecessary-generics": [false],
+      "strict-export-declare-modifiers": [false],
       "interface-name": [true, "never-prefix"],
       "ban-types": [true, ["Object", "Use {} instead."], ["String"], ["Number"]],
       "member-ordering": false,


Test patch:
diff --git a/test/appendFlipped.js b/test/appendFlipped.js
index e87ffff50e..fbce41f72e 100644
--- a/test/appendFlipped.js
+++ b/test/appendFlipped.js
@@ -1,21 +1,29 @@
+import { assert } from 'chai';
 import * as R from 'ramda';
 
 import * as RA from '../src';
-import eq from './shared/eq';
 
 describe('appendFlipped', function() {
   it('should add the element to the end of the list', function() {
-    eq(RA.appendFlipped(['x', 'y'], 'z'), ['x', 'y', 'z']);
-    eq(RA.appendFlipped(['x', 'y'], ['a', 'z']), ['x', 'y', ['a', 'z']]);
+    assert.sameOrderedMembers(RA.appendFlipped(['x', 'y'], 'z'), [
+      'x',
+      'y',
+      'z',
+    ]);
+    assert.sameDeepOrderedMembers(RA.appendFlipped(['x', 'y'], ['a', 'z']), [
+      'x',
+      'y',
+      ['a', 'z'],
+    ]);
   });
 
   it('should work on empty list', function() {
-    eq(RA.appendFlipped([], 1), [1]);
+    assert.sameOrderedMembers(RA.appendFlipped([], 1), [1]);
   });
 
   it('should support placeholder to specify "gaps"', function() {
     const appendFlipped = RA.appendFlipped(R.__);
 
-    eq(appendFlipped([], 'test'), ['test']);
+    assert.sameOrderedMembers(appendFlipped([], 'test'), ['test']);
   });
 });
diff --git a/test/async.js b/test/async.js
index 506b7e2d9d..fd046ae093 100644
--- a/test/async.js
+++ b/test/async.js
@@ -1,7 +1,6 @@
 import * as R from 'ramda';
 import { assert } from 'chai';
 
-import eq from './shared/eq';
 import * as RA from '../src';
 
 describe('async', function() {
@@ -15,7 +14,7 @@ describe('async', function() {
       });
       const expected = await asyncFn(1, 2);
 
-      eq(expected, 3);
+      assert.strictEqual(expected, 3);
     });
 
     context('and the generator throw Error as the last statement', function() {
@@ -32,7 +31,7 @@ describe('async', function() {
           throw new Error('fulfilling should fail');
         } catch (error) {
           assert.instanceOf(error, Error);
-          eq(error.message, 'generator error');
+          assert.strictEqual(error.message, 'generator error');
         }
       });
     });
@@ -49,7 +48,7 @@ describe('async', function() {
           throw new Error('fulfilling should fail');
         } catch (error) {
           assert.instanceOf(error, Error);
-          eq(error.message, 'generator error');
+          assert.strictEqual(error.message, 'generator error');
         }
       });
     });
@@ -66,7 +65,7 @@ describe('async', function() {
           throw new Error('fulfilling should fail');
         } catch (error) {
           assert.instanceOf(error, Error);
-          eq(error.message, 'generator error');
+          assert.strictEqual(error.message, 'generator error');
         }
       });
     });
@@ -92,7 +91,7 @@ describe('async', function() {
             return c + 3;
           });
 
-          eq(await bar(1, 2), 9);
+          assert.strictEqual(await bar(1, 2), 9);
         });
       }
     );
@@ -116,7 +115,7 @@ describe('async', function() {
           return c + 3;
         });
 
-        eq(await bar(1, 2), 9);
+        assert.strictEqual(await bar(1, 2), 9);
       });
     });
   });
@@ -136,7 +135,7 @@ describe('async', function() {
       return c + 3;
     });
 
-    eq(await bar(1, 2), 6);
+    assert.strictEqual(await bar(1, 2), 6);
   });
 
   it('should support async delegation', async function() {
@@ -154,7 +153,7 @@ describe('async', function() {
       return c + 3;
     });
 
-    eq(await bar(1, 2), 6);
+    assert.strictEqual(await bar(1, 2), 6);
   });
 
   it('should support recursion delegation', async function() {
@@ -168,7 +167,7 @@ describe('async', function() {
       return yield newVal;
     });
 
-    eq(await async(10), 1);
+    assert.strictEqual(await async(10), 1);
   });
 
   it('should curry', async function() {
@@ -179,7 +178,7 @@ describe('async', function() {
     });
     const expected = await asyncFn();
 
-    eq(expected, 2);
+    assert.strictEqual(expected, 2);
   });
 
   context('given wrapping of generator with arity of 2', function() {
@@ -193,12 +192,12 @@ describe('async', function() {
     });
 
     specify('should translate generator arity to wrapper', function() {
-      eq(asyncFn.length, 2);
+      assert.strictEqual(asyncFn.length, 2);
     });
 
     specify('should curry wrapper to appropriate arity', async function() {
-      eq(await asyncFn(1, 2), 3);
-      eq(await asyncFn(1)(2), 3);
+      assert.strictEqual(await asyncFn(1, 2), 3);
+      assert.strictEqual(await asyncFn(1)(2), 3);
     });
   });
 
@@ -216,13 +215,13 @@ describe('async', function() {
       specify('should not support placeholder', async function() {
         const expected = await asyncFn(R.__);
 
-        eq(expected, 1);
+        assert.strictEqual(expected, 1);
       });
 
       specify('should support call without arguments', async function() {
         const expected = await asyncFn();
 
-        eq(expected, 1);
+        assert.strictEqual(expected, 1);
       });
     });
   });
diff --git a/test/ceil.js b/test/ceil.js
index 3929ddfa5c..15d0ce0841 100644
--- a/test/ceil.js
+++ b/test/ceil.js
@@ -2,42 +2,41 @@ import * as R from 'ramda';
 import { assert } from 'chai';
 
 import * as RA from '../src';
-import eq from './shared/eq';
 import Symbol from './shared/Symbol';
 
 describe('ceil', function() {
   it('should ceil float to nearest integer', function() {
-    eq(RA.ceil(0.9), 1);
-    eq(RA.ceil(5.95), 6);
-    eq(RA.ceil(5.5), 6);
-    eq(RA.ceil(5.05), 6);
-    eq(RA.ceil(-5.05), -5);
-    eq(RA.ceil(-5.5), -5);
-    eq(RA.ceil(-5.95), -5);
+    assert.strictEqual(RA.ceil(0.9), 1);
+    assert.strictEqual(RA.ceil(5.95), 6);
+    assert.strictEqual(RA.ceil(5.5), 6);
+    assert.strictEqual(RA.ceil(5.05), 6);
+    assert.strictEqual(RA.ceil(-5.05), -5);
+    assert.strictEqual(RA.ceil(-5.5), -5);
+    assert.strictEqual(RA.ceil(-5.95), -5);
   });
 
   context('given integer number', function() {
     specify('should return original integer number', function() {
-      eq(RA.ceil(0), 0);
-      eq(RA.ceil(1), 1);
-      eq(RA.ceil(-1), -1);
+      assert.strictEqual(RA.ceil(0), 0);
+      assert.strictEqual(RA.ceil(1), 1);
+      assert.strictEqual(RA.ceil(-1), -1);
     });
   });
 
   context('given value that is not a number', function() {
     specify('should return NaN', function() {
-      eq(RA.ceil(undefined), NaN);
-      eq(RA.ceil(NaN), NaN);
-      eq(RA.ceil({}), NaN);
-      eq(RA.ceil(/a/), NaN);
-      eq(RA.ceil('test'), NaN);
-      eq(RA.ceil(new Error()), NaN);
+      assert.isNaN(RA.ceil(undefined));
+      assert.isNaN(RA.ceil(NaN));
+      assert.isNaN(RA.ceil({}));
+      assert.isNaN(RA.ceil(/a/));
+      assert.isNaN(RA.ceil('test'));
+      assert.isNaN(RA.ceil(new Error()));
     });
   });
 
   context('given null', function() {
     specify('should return 0', function() {
-      eq(RA.ceil(null), 0);
+      assert.strictEqual(RA.ceil(null), 0);
     });
   });
 
@@ -61,21 +60,21 @@ describe('ceil', function() {
     specify(
       'should return the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC',
       function() {
-        eq(RA.ceil(new Date(2)), 2);
+        assert.strictEqual(RA.ceil(new Date(2)), 2);
       }
     );
   });
 
   context('given Infinity value', function() {
     specify('should return untouched Infinity value', function() {
-      eq(RA.ceil(Infinity), Infinity);
-      eq(RA.ceil(-Infinity), -Infinity);
+      assert.strictEqual(RA.ceil(Infinity), Infinity);
+      assert.strictEqual(RA.ceil(-Infinity), -Infinity);
     });
   });
 
   it('should support placeholder to specify "gaps"', function() {
     const ceil = RA.ceil(R.__);
 
-    eq(ceil(0.9), 1);
+    assert.strictEqual(ceil(0.9), 1);
   });
 });
diff --git a/test/compact.js b/test/compact.js
index da6b788ac5..59a6c592f3 100644
--- a/test/compact.js
+++ b/test/compact.js
@@ -2,18 +2,20 @@ import { assert } from 'chai';
 import * as R from 'ramda';
 
 import * as RA from '../src';
-import eq from './shared/eq';
 
 describe('compact', function() {
   context('given list contains falsy values', function() {
     specify('should filter them', function() {
-      eq(RA.compact([0, 1, false, 2, '', 3, null, undefined, NaN]), [1, 2, 3]);
+      assert.sameOrderedMembers(
+        RA.compact([0, 1, false, 2, '', 3, null, undefined, NaN]),
+        [1, 2, 3]
+      );
     });
   });
 
   context('given list contains truthy values only', function() {
     specify('should not filter anything', function() {
-      eq(RA.compact([1, 2, 3]), [1, 2, 3]);
+      assert.sameOrderedMembers(RA.compact([1, 2, 3]), [1, 2, 3]);
     });
 
     specify('should return new list with exactly same items', function() {
@@ -34,6 +36,6 @@ describe('compact', function() {
   it('should support placeholder to specify "gaps"', function() {
     const compact = RA.compact(R.__);
 
-    eq(compact([]), []);
+    assert.sameOrderedMembers(compact([]), []);
   });
 });
diff --git a/test/concatAll.js b/test/concatAll.js
index 2b0810a3c7..a7444bdb5e 100644
--- a/test/concatAll.js
+++ b/test/concatAll.js
@@ -3,24 +3,23 @@ import { NEL, Nil } from 'monet';
 import * as R from 'ramda';
 
 import * as RA from '../src';
-import eq from './shared/eq';
 
 describe('concatAll', function() {
   it('should concatenate arrays', function() {
-    eq(RA.concatAll([[1], [2], [3]]), [1, 2, 3]);
+    assert.sameOrderedMembers(RA.concatAll([[1], [2], [3]]), [1, 2, 3]);
   });
 
   it('should concatenate strings', function() {
-    eq(RA.concatAll(['1', '2', '3']), '123');
+    assert.strictEqual(RA.concatAll(['1', '2', '3']), '123');
   });
 
   it('should concatenate semigroups', function() {
-    eq(RA.concatAll([NEL(1), NEL(2)]), NEL(1, NEL(2, Nil)));
+    assert.deepEqual(RA.concatAll([NEL(1), NEL(2)]), NEL(1, NEL(2, Nil)));
   });
 
   context('given foldable is empty', function() {
     specify('should returns undefined', function() {
-      eq(RA.concatAll([]), undefined);
+      assert.isUndefined(RA.concatAll([]));
     });
   });
 
@@ -48,6 +47,6 @@ describe('concatAll', function() {
   it('should support placeholder to specify "gaps"', function() {
     const concatAll = RA.concatAll(R.__);
 
-    eq(concatAll(['1', '2', '3']), '123');
+    assert.strictEqual(concatAll(['1', '2', '3']), '123');
   });
 });
diff --git a/test/concatRight.js b/test/concatRight.js
index 6acef77936..70cd969865 100644
--- a/test/concatRight.js
+++ b/test/concatRight.js
@@ -1,7 +1,6 @@
 import * as R from 'ramda';
 import { assert } from 'chai';
 
-import eq from './shared/eq';
 import * as RA from '../src';
 
 describe('concatRight', function() {
@@ -14,31 +13,43 @@ describe('concatRight', function() {
   const z2 = { x: 'z2' };
 
   it('should add combines the elements of the two lists', function() {
-    eq(RA.concatRight(['a', 'b'], ['c', 'd']), ['c', 'd', 'a', 'b']);
-    eq(RA.concatRight([], ['c', 'd']), ['c', 'd']);
+    assert.sameOrderedMembers(RA.concatRight(['a', 'b'], ['c', 'd']), [
+      'c',
+      'd',
+      'a',
+      'b',
+    ]);
+    assert.sameOrderedMembers(RA.concatRight([], ['c', 'd']), ['c', 'd']);
   });
 
   it('should work on strings', function() {
-    eq(RA.concatRight('foo', 'bar'), 'barfoo');
-    eq(RA.concatRight('x', ''), 'x');
-    eq(RA.concatRight('', 'x'), 'x');
-    eq(RA.concatRight('', ''), '');
+    assert.strictEqual(RA.concatRight('foo', 'bar'), 'barfoo');
+    assert.strictEqual(RA.concatRight('x', ''), 'x');
+    assert.strictEqual(RA.concatRight('', 'x'), 'x');
+    assert.strictEqual(RA.concatRight('', ''), '');
   });
 
   it('should delegate to non-String object with a concat method, as first param', function() {
-    eq(RA.concatRight(z2, z1), 'z1 z2');
+    assert.strictEqual(RA.concatRight(z2, z1), 'z1 z2');
   });
 
   it('should be curried', function() {
     const conc123 = RA.concatRight([1, 2, 3]);
-    eq(conc123([4, 5, 6]), [4, 5, 6, 1, 2, 3]);
-    eq(conc123(['a', 'b', 'c']), ['a', 'b', 'c', 1, 2, 3]);
+    assert.sameOrderedMembers(conc123([4, 5, 6]), [4, 5, 6, 1, 2, 3]);
+    assert.sameOrderedMembers(conc123(['a', 'b', 'c']), [
+      'a',
+      'b',
+      'c',
+      1,
+      2,
+      3,
+    ]);
   });
 
   it('should be curried like a binary operator, that accepts an initial placeholder', function() {
     const appendBar = RA.concatRight(R.__, 'bar');
-    eq(typeof appendBar, 'function');
-    eq(appendBar('foo'), 'barfoo');
+    assert.strictEqual(typeof appendBar, 'function');
+    assert.strictEqual(appendBar('foo'), 'barfoo');
   });
 
   context('given attempting to combine an array with a non-array', function() {
@@ -57,7 +68,17 @@ describe('concatRight', function() {
   );
 
   it('should curry', function() {
-    eq(RA.concatRight(['a', 'b'], ['c', 'd']), ['c', 'd', 'a', 'b']);
-    eq(RA.concatRight(['a', 'b'])(['c', 'd']), ['c', 'd', 'a', 'b']);
+    assert.sameOrderedMembers(RA.concatRight(['a', 'b'], ['c', 'd']), [
+      'c',
+      'd',
+      'a',
+      'b',
+    ]);
+    assert.sameOrderedMembers(RA.concatRight(['a', 'b'])(['c', 'd']), [
+      'c',
+      'd',
+      'a',
+      'b',
+    ]);
   });
 });
diff --git a/test/contained.js b/test/contained.js
index 4ec1a58379..f271111d2f 100644
--- a/test/contained.js
+++ b/test/contained.js
@@ -1,24 +1,24 @@
 import * as R from 'ramda';
+import { assert } from 'chai';
 
 import * as RA from '../src';
-import eq from './shared/eq';
 
 describe('contained', function() {
   context('given element is in the list', function() {
     specify('should return true', function() {
-      eq(RA.contained([1, 2, 3, 9, 8, 7, 100, 200, 300], 7), true);
+      assert.isTrue(RA.contained([1, 2, 3, 9, 8, 7, 100, 200, 300], 7));
     });
   });
 
   context('given element is not in the list', function() {
     specify('should return false', function() {
-      eq(RA.contained([1, 2, 3, 9, 8, 7, 100, 200, 300], 99), false);
+      assert.isFalse(RA.contained([1, 2, 3, 9, 8, 7, 100, 200, 300], 99));
     });
   });
 
   context('given empty list', function() {
     specify('should return false', function() {
-      eq(RA.contained([], 1), false);
+      assert.isFalse(RA.contained([], 1));
     });
   });
 
@@ -30,20 +30,20 @@ describe('contained', function() {
       return x instanceof Just && R.equals(x.value, this.value);
     };
 
-    eq(RA.contained([-0], 0), false);
-    eq(RA.contained([0], -0), false);
-    eq(RA.contained([NaN], NaN), true);
-    eq(RA.contained([new Just([42])], new Just([42])), true);
+    assert.isFalse(RA.contained([-0], 0));
+    assert.isFalse(RA.contained([0], -0));
+    assert.isTrue(RA.contained([NaN], NaN));
+    assert.isTrue(RA.contained([new Just([42])], new Just([42])));
   });
 
   context('given substring is part of string', function() {
     it('should return true', function() {
-      eq(RA.contained('banana', 'ba'), true);
+      assert.isTrue(RA.contained('banana', 'ba'));
     });
   });
 
   it('should be curried', function() {
-    eq(RA.contained('abcd', 'b'), true);
-    eq(RA.contained('abcd')('b'), true);
+    assert.isTrue(RA.contained('abcd', 'b'));
+    assert.isTrue(RA.contained('abcd')('b'));
   });
 });
diff --git a/test/curryRight.js b/test/curryRight.js
index b9a98b1fe8..8deba16cab 100644
--- a/test/curryRight.js
+++ b/test/curryRight.js
@@ -1,7 +1,7 @@
 import * as R from 'ramda';
 import jsv from 'jsverify';
+import { assert } from 'chai';
 
-import eq from './shared/eq';
 import * as RA from '../src';
 
 describe('curryRight', function() {
@@ -10,7 +10,7 @@ describe('curryRight', function() {
       return (a + b * c) / d;
     }); // f(2, 6, 3, 10) == 2
     const g = f(10);
-    eq(g(3, 6, 2), 2);
+    assert.strictEqual(g(3, 6, 2), 2);
   });
 
   it('should curry multiple values', function() {
@@ -19,9 +19,9 @@ describe('curryRight', function() {
       return (a + b * c) / d;
     });
     const g = f(10, 3);
-    eq(g(6, 2), 2);
+    assert.strictEqual(g(6, 2), 2);
     const h = f(10, 3, 6);
-    eq(h(2), 2);
+    assert.strictEqual(h(2), 2);
   });
 
   it('should allow further currying of a curried function', function() {
@@ -30,22 +30,22 @@ describe('curryRight', function() {
       return (a + b * c) / d;
     });
     const g = f(10);
-    eq(g(3, 6, 2), 2);
+    assert.strictEqual(g(3, 6, 2), 2);
     const h = g(3);
-    eq(h(6, 2), 2);
-    eq(g(3, 6)(2), 2);
+    assert.strictEqual(h(6, 2), 2);
+    assert.strictEqual(g(3, 6)(2), 2);
   });
 
   it('should properly report the length of the curried function', function() {
     const f = RA.curryRight(function(a, b, c, d) {
       return (a + b * c) / d;
     });
-    eq(f.length, 4);
+    assert.strictEqual(f.length, 4);
     const g = f(10);
-    eq(g.length, 3);
+    assert.strictEqual(g.length, 3);
     const h = g(3);
-    eq(h.length, 2);
-    eq(g(3, 6).length, 1);
+    assert.strictEqual(h.length, 2);
+    assert.strictEqual(g(3, 6).length, 1);
   });
 
   it('should preserve context', function() {
@@ -55,8 +55,8 @@ describe('curryRight', function() {
     };
     const g = RA.curryRight(f);
 
-    eq(g.call(ctx, 2, 4), 24);
-    eq(g.call(ctx, 2).call(ctx, 4), 24);
+    assert.strictEqual(g.call(ctx, 2, 4), 24);
+    assert.strictEqual(g.call(ctx, 2).call(ctx, 4), 24);
   });
 
   it('should support R.__ placeholder', function() {
@@ -66,29 +66,29 @@ describe('curryRight', function() {
     const g = RA.curryRight(f);
     const _ = R.__;
 
-    eq(g(1)(2)(3), [3, 2, 1]);
-    eq(g(1)(2, 3), [3, 2, 1]);
-    eq(g(1, 2)(3), [3, 2, 1]);
-    eq(g(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, 3), [3, 2, 1]);
 
-    eq(g(_, 2, 3)(1), [3, 2, 1]);
-    eq(g(1, _, 3)(2), [3, 2, 1]);
-    eq(g(1, 2, _)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, 3)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, 3)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, _)(3), [3, 2, 1]);
 
-    eq(g(1, _, _)(2)(3), [3, 2, 1]);
-    eq(g(_, 2, _)(1)(3), [3, 2, 1]);
-    eq(g(_, _, 3)(1)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(1)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(1)(2), [3, 2, 1]);
 
-    eq(g(1, _, _)(2, 3), [3, 2, 1]);
-    eq(g(_, 2, _)(1, 3), [3, 2, 1]);
-    eq(g(_, _, 3)(1, 2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(1, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(1, 2), [3, 2, 1]);
 
-    eq(g(1, _, _)(_, 3)(2), [3, 2, 1]);
-    eq(g(_, 2, _)(_, 3)(1), [3, 2, 1]);
-    eq(g(_, _, 3)(_, 2)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(_, 3)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(_, 3)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(_, 2)(1), [3, 2, 1]);
 
-    eq(g(_, _, _)(_, _)(_)(1, 2, 3), [3, 2, 1]);
-    eq(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, _)(_, _)(_)(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [3, 2, 1]);
   });
 
   it('should support @@functional/placeholder', function() {
@@ -98,29 +98,29 @@ describe('curryRight', function() {
     const g = RA.curryRight(f);
     const _ = { '@@functional/placeholder': true, x: Math.random() };
 
-    eq(g(1)(2)(3), [3, 2, 1]);
-    eq(g(1)(2, 3), [3, 2, 1]);
-    eq(g(1, 2)(3), [3, 2, 1]);
-    eq(g(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, 3), [3, 2, 1]);
 
-    eq(g(_, 2, 3)(1), [3, 2, 1]);
-    eq(g(1, _, 3)(2), [3, 2, 1]);
-    eq(g(1, 2, _)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, 3)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, 3)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, _)(3), [3, 2, 1]);
 
-    eq(g(1, _, _)(2)(3), [3, 2, 1]);
-    eq(g(_, 2, _)(1)(3), [3, 2, 1]);
-    eq(g(_, _, 3)(1)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(1)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(1)(2), [3, 2, 1]);
 
-    eq(g(1, _, _)(2, 3), [3, 2, 1]);
-    eq(g(_, 2, _)(1, 3), [3, 2, 1]);
-    eq(g(_, _, 3)(1, 2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(1, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(1, 2), [3, 2, 1]);
 
-    eq(g(1, _, _)(_, 3)(2), [3, 2, 1]);
-    eq(g(_, 2, _)(_, 3)(1), [3, 2, 1]);
-    eq(g(_, _, 3)(_, 2)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(_, 3)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(_, 3)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(_, 2)(1), [3, 2, 1]);
 
-    eq(g(_, _, _)(_, _)(_)(1, 2, 3), [3, 2, 1]);
-    eq(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, _)(_, _)(_)(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [3, 2, 1]);
   });
 
   it('should forward extra arguments', function() {
@@ -130,11 +130,11 @@ describe('curryRight', function() {
     };
     const g = RA.curryRight(f);
 
-    eq(g(1, 2, 3), [3, 2, 1]);
-    eq(g(1, 2, 3, 4), [4, 3, 2, 1]);
-    eq(g(1, 2)(3, 4), [4, 3, 2, 1]);
-    eq(g(1)(2, 3, 4), [4, 3, 2, 1]);
-    eq(g(1)(2)(3, 4), [4, 3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, 3, 4), [4, 3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2)(3, 4), [4, 3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2, 3, 4), [4, 3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2)(3, 4), [4, 3, 2, 1]);
   });
 });
 
diff --git a/test/curryRightN.js b/test/curryRightN.js
index 7c1809a0b5..f217e65275 100644
--- a/test/curryRightN.js
+++ b/test/curryRightN.js
@@ -1,6 +1,6 @@
 import * as R from 'ramda';
+import { assert } from 'chai';
 
-import eq from './shared/eq';
 import * as RA from '../src';
 
 describe('curryRightN', function() {
@@ -11,20 +11,20 @@ describe('curryRightN', function() {
 
   it('should accept an arity', function() {
     const curried = RA.curryRightN(3, source);
-    eq(curried(1)(2)(3), 6);
-    eq(curried(1, 2)(3), 6);
-    eq(curried(1)(2, 3), 6);
-    eq(curried(1, 2, 3), 6);
+    assert.strictEqual(curried(1)(2)(3), 6);
+    assert.strictEqual(curried(1, 2)(3), 6);
+    assert.strictEqual(curried(1)(2, 3), 6);
+    assert.strictEqual(curried(1, 2, 3), 6);
   });
 
   it('should support partial application/currying', function() {
     const curryRight3 = RA.curryRightN(3);
     const curried = curryRight3(source);
-    eq(curried.length, 3);
-    eq(curried(1)(2)(3), 6);
-    eq(curried(1, 2)(3), 6);
-    eq(curried(1)(2, 3), 6);
-    eq(curried(1, 2, 3), 6);
+    assert.strictEqual(curried.length, 3);
+    assert.strictEqual(curried(1)(2)(3), 6);
+    assert.strictEqual(curried(1, 2)(3), 6);
+    assert.strictEqual(curried(1)(2, 3), 6);
+    assert.strictEqual(curried(1, 2, 3), 6);
   });
 
   it('should preserve context', function() {
@@ -34,8 +34,8 @@ describe('curryRightN', function() {
     };
     const g = RA.curryRightN(2, f);
 
-    eq(g.call(ctx, 2, 4), 24);
-    eq(g.call(ctx, 2).call(ctx, 4), 24);
+    assert.strictEqual(g.call(ctx, 2, 4), 24);
+    assert.strictEqual(g.call(ctx, 2).call(ctx, 4), 24);
   });
 
   it('should support R.__ placeholder', function() {
@@ -45,29 +45,29 @@ describe('curryRightN', function() {
     const g = RA.curryRightN(3, f);
     const _ = R.__;
 
-    eq(g(1)(2)(3), [3, 2, 1]);
-    eq(g(1)(2, 3), [3, 2, 1]);
-    eq(g(1, 2)(3), [3, 2, 1]);
-    eq(g(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, 3), [3, 2, 1]);
 
-    eq(g(_, 2, 3)(1), [3, 2, 1]);
-    eq(g(1, _, 3)(2), [3, 2, 1]);
-    eq(g(1, 2, _)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, 3)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, 3)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, _)(3), [3, 2, 1]);
 
-    eq(g(1, _, _)(2)(3), [3, 2, 1]);
-    eq(g(_, 2, _)(1)(3), [3, 2, 1]);
-    eq(g(_, _, 3)(1)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(1)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(1)(2), [3, 2, 1]);
 
-    eq(g(1, _, _)(2, 3), [3, 2, 1]);
-    eq(g(_, 2, _)(1, 3), [3, 2, 1]);
-    eq(g(_, _, 3)(1, 2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(1, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(1, 2), [3, 2, 1]);
 
-    eq(g(1, _, _)(_, 3)(2), [3, 2, 1]);
-    eq(g(_, 2, _)(_, 3)(1), [3, 2, 1]);
-    eq(g(_, _, 3)(_, 2)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(_, 3)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(_, 3)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(_, 2)(1), [3, 2, 1]);
 
-    eq(g(_, _, _)(_, _)(_)(1, 2, 3), [3, 2, 1]);
-    eq(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, _)(_, _)(_)(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [3, 2, 1]);
   });
 
   it('should support @@functional/placeholder', function() {
@@ -77,29 +77,29 @@ describe('curryRightN', function() {
     const g = RA.curryRightN(3, f);
     const _ = { '@@functional/placeholder': true, x: Math.random() };
 
-    eq(g(1)(2)(3), [3, 2, 1]);
-    eq(g(1)(2, 3), [3, 2, 1]);
-    eq(g(1, 2)(3), [3, 2, 1]);
-    eq(g(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, 3), [3, 2, 1]);
 
-    eq(g(_, 2, 3)(1), [3, 2, 1]);
-    eq(g(1, _, 3)(2), [3, 2, 1]);
-    eq(g(1, 2, _)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, 3)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, 3)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, _)(3), [3, 2, 1]);
 
-    eq(g(1, _, _)(2)(3), [3, 2, 1]);
-    eq(g(_, 2, _)(1)(3), [3, 2, 1]);
-    eq(g(_, _, 3)(1)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(2)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(1)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(1)(2), [3, 2, 1]);
 
-    eq(g(1, _, _)(2, 3), [3, 2, 1]);
-    eq(g(_, 2, _)(1, 3), [3, 2, 1]);
-    eq(g(_, _, 3)(1, 2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(1, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(1, 2), [3, 2, 1]);
 
-    eq(g(1, _, _)(_, 3)(2), [3, 2, 1]);
-    eq(g(_, 2, _)(_, 3)(1), [3, 2, 1]);
-    eq(g(_, _, 3)(_, 2)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, _, _)(_, 3)(2), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, 2, _)(_, 3)(1), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, 3)(_, 2)(1), [3, 2, 1]);
 
-    eq(g(_, _, _)(_, _)(_)(1, 2, 3), [3, 2, 1]);
-    eq(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, _)(_, _)(_)(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(_, _, _)(1, _, _)(_, _)(2, _)(_)(3), [3, 2, 1]);
   });
 
   it('should forward extra arguments', function() {
@@ -108,10 +108,10 @@ describe('curryRightN', function() {
     };
     const g = RA.curryRightN(3, f);
 
-    eq(g(1, 2, 3), [3, 2, 1]);
-    eq(g(1, 2, 3, 4), [4, 3, 2, 1]);
-    eq(g(1, 2)(3, 4), [4, 3, 2, 1]);
-    eq(g(1)(2, 3, 4), [4, 3, 2, 1]);
-    eq(g(1)(2)(3, 4), [4, 3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, 3), [3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2, 3, 4), [4, 3, 2, 1]);
+    assert.sameOrderedMembers(g(1, 2)(3, 4), [4, 3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2, 3, 4), [4, 3, 2, 1]);
+    assert.sameOrderedMembers(g(1)(2)(3, 4), [4, 3, 2, 1]);
   });
 });
diff --git a/test/defaultWhen.js b/test/defaultWhen.js
index 8cec57003c..d01c3b1cd0 100644
--- a/test/defaultWhen.js
+++ b/test/defaultWhen.js
@@ -1,20 +1,21 @@
+import { assert } from 'chai';
+
 import * as RA from '../src';
-import eq from './shared/eq';
 
 describe('defaultWhen', function() {
   it('should return default value', function() {
-    eq(RA.defaultWhen(RA.isNull, 1, null), 1);
-    eq(RA.defaultWhen(RA.isString, 2, ''), 2);
+    assert.strictEqual(RA.defaultWhen(RA.isNull, 1, null), 1);
+    assert.strictEqual(RA.defaultWhen(RA.isString, 2, ''), 2);
   });
 
   it('should return value', function() {
-    eq(RA.defaultWhen(RA.isNull, 1, undefined), undefined);
-    eq(RA.defaultWhen(RA.isString, 2, 3), 3);
+    assert.isUndefined(RA.defaultWhen(RA.isNull, 1, undefined));
+    assert.strictEqual(RA.defaultWhen(RA.isString, 2, 3), 3);
   });
 
   it('should curry', function() {
-    eq(RA.defaultWhen(RA.isNull)(1)(null), 1);
-    eq(RA.defaultWhen(RA.isNull, 1)(null), 1);
-    eq(RA.defaultWhen(RA.isNull, 1, null), 1);
+    assert.strictEqual(RA.defaultWhen(RA.isNull)(1)(null), 1);
+    assert.strictEqual(RA.defaultWhen(RA.isNull, 1)(null), 1);
+    assert.strictEqual(RA.defaultWhen(RA.isNull, 1, null), 1);
   });
 });
diff --git a/test/dispatch.js b/test/dispatch.js
index 533102c358..8fe6320fe2 100644
--- a/test/dispatch.js
+++ b/test/dispatch.js
@@ -3,7 +3,6 @@ import { assert } from 'chai';
 import sinon from 'sinon';
 
 import * as RA from '../src';
-import eq from './shared/eq';
 
 describe('dispatch', function() {
   it('should return first non-nil value', function() {
@@ -29,7 +28,7 @@ describe('dispatch', function() {
   it('should return curried function with max arity', function() {
     const fn = RA.dispatch([R.divide, R.identity]);
 
-    eq(fn.length, 2);
+    assert.strictEqual(fn.length, 2);
   });
 
   it('should act as switch', function() {
@@ -72,7 +71,7 @@ describe('dispatch', function() {
 
   context('given empty array provided as input', function() {
     specify('should return undefined', function() {
-      eq(RA.dispatch([]), undefined);
+      assert.isUndefined(RA.dispatch([]));
     });
   });
 
@@ -80,7 +79,7 @@ describe('dispatch', function() {
     specify('should return undefined', function() {
       const configuredDispatch = RA.dispatch([RA.stubUndefined, RA.stubNull]);
 
-      eq(configuredDispatch(), undefined);
+      assert.isUndefined(configuredDispatch());
     });
   });
 
@@ -90,7 +89,7 @@ describe('dispatch', function() {
       specify('should return undefined', function() {
         const configuredDispatch = RA.dispatch([() => {}, () => {}]);
 
-        eq(configuredDispatch(), undefined);
+        assert.isUndefined(configuredDispatch());
       });
     }
   );
@@ -98,6 +97,6 @@ describe('dispatch', function() {
   it('should support placeholder to specify "gaps"', function() {
     const dispatch = RA.dispatch(R.__);
 
-    eq(dispatch([RA.stubNull, R.always(1)])(), 1);
+    assert.strictEqual(dispatch([RA.stubNull, R.always(1)])(), 1);
   });
 });
diff --git a/test/mocha-testem.mustache b/test/mocha-testem.mustache
new file mode 100644
index 0000000000..c6a39f83a1
--- /dev/null
+++ b/test/mocha-testem.mustache
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+<head>
+    <title>Test'em</title>
+    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/mocha/6.2.0/mocha.css">
+    <script src="//cdnjs.cloudflare.com/ajax/libs/mocha/6.2.0/mocha.js"></script>
+    <script src="//cdnjs.cloudflare.com/ajax/libs/chai/4.2.0/chai.js"></script>
+    <script src="/testem.js"></script>
+    <script>
+        mocha.setup('bdd');
+    </script>
+    <script src="../tmp-test-bundle.js"></script>
+</head>
+<body>
+<div id="mocha"></div>
+<script>
+    mocha.run();
+</script>
+</body>
+</html>
diff --git a/test/padCharsEnd.js b/test/padCharsEnd.js
index 952aa84cb0..9163be409f 100644
--- a/test/padCharsEnd.js
+++ b/test/padCharsEnd.js
@@ -70,7 +70,7 @@ describe('padCharsEnd', function() {
   });
 
   context('padCharsEndStrInvoker', function() {
-    beforeEach(function() {
+    before(function() {
       if (RA.isNotFunction(String.prototype.padEnd)) {
         this.skip();
       }
diff --git a/test/padEnd.js b/test/padEnd.js
new file mode 100644
index 0000000000..c13c5d772c
--- /dev/null
+++ b/test/padEnd.js
@@ -0,0 +1,46 @@
+import * as RA from '../src';
+import eq from './shared/eq';
+
+describe('padEnd', function() {
+  specify('should pad string with spaces', function() {
+    eq(RA.padEnd(3, 'a'), 'a  ');
+  });
+
+  context('given targetLength as 0', function() {
+    specify('should return original string', function() {
+      eq(RA.padEnd(0, 'abc'), 'abc');
+    });
+  });
+
+  context('given targetLength less than string length', function() {
+    specify('should return original string', function() {
+      eq(RA.padEnd(1, 'abc'), 'abc');
+    });
+  });
+
+  context('given targetLength supplied as float', function() {
+    specify('should convert targetLength to integer', function() {
+      eq(RA.padEnd(7.5, 'abc'), 'abc    ');
+    });
+  });
+
+  context(
+    'given targetLength is a value coercible to valid integer number',
+    function() {
+      specify('should return padded string', function() {
+        eq(RA.padEnd('5', 'abc'), 'abc  ');
+      });
+    }
+  );
+
+  context('given targeLength is a negative number', function() {
+    specify('should return original string', function() {
+      eq(RA.padEnd(-10, 'abc'), 'abc');
+    });
+  });
+
+  specify('should be curried', function() {
+    eq(RA.padEnd(5, 'abc'), 'abc  ');
+    eq(RA.padEnd(5)('abc'), 'abc  ');
+  });
+});
diff --git a/test/repeatStr.js b/test/repeatStr.js
index 8143b6c38f..7fc2764427 100644
--- a/test/repeatStr.js
+++ b/test/repeatStr.js
@@ -54,7 +54,7 @@ describe('repeatStr', function() {
   });
 
   context('repeatStrInvoker', function() {
-    beforeEach(function() {
+    before(function() {
       if (RA.isNotFunction(String.prototype.repeat)) {
         this.skip();
       }
diff --git a/test/replaceAll.js b/test/replaceAll.js
index 4e12413725..dc5fae05df 100644
--- a/test/replaceAll.js
+++ b/test/replaceAll.js
@@ -1,7 +1,7 @@
 import { assert } from 'chai';
 
 import * as RA from '../src';
-import { replaceAllPolyfill } from '../src/replaceAll';
+import { replaceAllPolyfill, replaceAllInvoker } from '../src/replaceAll';
 
 describe('replaceAll', function() {
   it('should replace all matches', function() {
@@ -36,6 +36,12 @@ describe('replaceAll', function() {
     assert.strictEqual(actual, expected);
   });
 
+  context('given searchValue is a non-global RegExp', function() {
+    specify('should throw Error', function() {
+      assert.throws(() => RA.replaceAll(/a/, 'c', 'abc'), TypeError);
+    });
+  });
+
   it('should curry', function() {
     assert.strictEqual(RA.replaceAll('a', 'c', 'aba'), 'cbc');
     assert.strictEqual(RA.replaceAll('a')('c', 'aba'), 'cbc');
@@ -43,72 +49,135 @@ describe('replaceAll', function() {
     assert.strictEqual(RA.replaceAll('a')('c')('aba'), 'cbc');
   });
 
-  context('given searchValue is a non-global RegExp', function() {
-    specify('should throw Error', function() {
-      assert.throws(() => RA.replaceAll(/a/, 'c', 'abc'), TypeError);
+  context('replaceAllInvoker', function() {
+    before(function() {
+      if (RA.isNotFunction(String.prototype.replaceAll)) {
+        this.skip();
+      }
     });
-  });
-});
 
-describe('replaceAllPolyfill', function() {
-  context('given searchValue is a non-global RegExp', function() {
-    specify('should throw Error', function() {
-      assert.throws(() => replaceAllPolyfill(/a/, 'c', 'abc'), TypeError);
+    context('given searchValue is a non-global RegExp', function() {
+      specify('should throw Error', function() {
+        assert.throws(() => replaceAllInvoker(/a/, 'c', 'abc'), TypeError);
+      });
     });
-  });
 
-  it('should support global RegExp searchValue', function() {
-    const value = 'xxx';
-    const actual = replaceAllPolyfill(/x/g, 'v', value);
-    const expected = 'vvv';
+    specify('should support global RegExp searchValue', function() {
+      const value = 'xxx';
+      const actual = replaceAllInvoker(/x/g, 'v', value);
+      const expected = 'vvv';
 
-    assert.strictEqual(actual, expected);
-  });
+      assert.strictEqual(actual, expected);
+    });
 
-  it('should support empty searchValue', function() {
-    const value = 'xxx';
-    const actual = replaceAllPolyfill('', '_', value);
-    const expected = '_x_x_x_';
+    specify('should support empty searchValue', function() {
+      const value = 'xxx';
+      const actual = replaceAllInvoker('', '_', value);
+      const expected = '_x_x_x_';
 
-    assert.strictEqual(actual, expected);
-  });
+      assert.strictEqual(actual, expected);
+    });
 
-  it('should replace all matches', function() {
-    const value = 'ab cd ab cd ab cd';
-    const actual = replaceAllPolyfill('ab', 'ef', value);
-    const expected = 'ef cd ef cd ef cd';
+    specify('should replace all matches', function() {
+      const value = 'ab cd ab cd ab cd';
+      const actual = replaceAllInvoker('ab', 'ef', value);
+      const expected = 'ef cd ef cd ef cd';
 
-    assert.strictEqual(actual, expected);
-  });
+      assert.strictEqual(actual, expected);
+    });
 
-  context('given empty string', function() {
-    specify('should return original value', function() {
-      assert.strictEqual(replaceAllPolyfill('a', 'c', ''), '');
+    context('given empty string', function() {
+      specify('should return original value', function() {
+        assert.strictEqual(replaceAllInvoker('a', 'c', ''), '');
+      });
     });
-  });
 
-  it('should support boxing wrappers', function() {
-    const value = new String('ab cd ab cd ab cd');
-    const searchValue = new String('ab');
-    const replaceValue = new String('ef');
-    const actual = replaceAllPolyfill(searchValue, replaceValue, value);
-    const expected = 'ef cd ef cd ef cd';
+    specify('should support boxing wrappers', function() {
+      const value = new String('ab cd ab cd ab cd');
+      const searchValue = new String('ab');
+      const replaceValue = new String('ef');
+      const actual = replaceAllInvoker(searchValue, replaceValue, value);
+      const expected = 'ef cd ef cd ef cd';
 
-    assert.strictEqual(actual, expected);
-  });
+      assert.strictEqual(actual, expected);
+    });
 
-  it('should replace in very big strings', function() {
-    const bigString = 'ab cd'.repeat(10000);
-    const expected = 'ab ef'.repeat(10000);
-    const actual = replaceAllPolyfill('cd', 'ef', bigString);
+    specify('should replace in very big strings', function() {
+      const bigString = 'ab cd'.repeat(10000);
+      const expected = 'ab ef'.repeat(10000);
+      const actual = replaceAllInvoker('cd', 'ef', bigString);
 
-    assert.strictEqual(actual, expected);
+      assert.strictEqual(actual, expected);
+    });
+
+    specify('should curry', function() {
+      assert.strictEqual(replaceAllInvoker('a', 'c', 'aba'), 'cbc');
+      assert.strictEqual(replaceAllInvoker('a')('c', 'aba'), 'cbc');
+      assert.strictEqual(replaceAllInvoker('a', 'c')('aba'), 'cbc');
+      assert.strictEqual(replaceAllInvoker('a')('c')('aba'), 'cbc');
+    });
   });
 
-  it('should curry', function() {
-    assert.strictEqual(replaceAllPolyfill('a', 'c', 'aba'), 'cbc');
-    assert.strictEqual(replaceAllPolyfill('a')('c', 'aba'), 'cbc');
-    assert.strictEqual(replaceAllPolyfill('a', 'c')('aba'), 'cbc');
-    assert.strictEqual(replaceAllPolyfill('a')('c')('aba'), 'cbc');
+  context('replaceAllPolyfill', function() {
+    context('given searchValue is a non-global RegExp', function() {
+      specify('should throw Error', function() {
+        assert.throws(() => replaceAllPolyfill(/a/, 'c', 'abc'), TypeError);
+      });
+    });
+
+    specify('should support global RegExp searchValue', function() {
+      const value = 'xxx';
+      const actual = replaceAllPolyfill(/x/g, 'v', value);
+      const expected = 'vvv';
+
+      assert.strictEqual(actual, expected);
+    });
+
+    specify('should support empty searchValue', function() {
+      const value = 'xxx';
+      const actual = replaceAllPolyfill('', '_', value);
+      const expected = '_x_x_x_';
+
+      assert.strictEqual(actual, expected);
+    });
+
+    specify('should replace all matches', function() {
+      const value = 'ab cd ab cd ab cd';
+      const actual = replaceAllPolyfill('ab', 'ef', value);
+      const expected = 'ef cd ef cd ef cd';
+
+      assert.strictEqual(actual, expected);
+    });
+
+    context('given empty string', function() {
+      specify('should return original value', function() {
+        assert.strictEqual(replaceAllPolyfill('a', 'c', ''), '');
+      });
+    });
+
+    specify('should support boxing wrappers', function() {
+      const value = new String('ab cd ab cd ab cd');
+      const searchValue = new String('ab');
+      const replaceValue = new String('ef');
+      const actual = replaceAllPolyfill(searchValue, replaceValue, value);
+      const expected = 'ef cd ef cd ef cd';
+
+      assert.strictEqual(actual, expected);
+    });
+
+    specify('should replace in very big strings', function() {
+      const bigString = 'ab cd'.repeat(10000);
+      const expected = 'ab ef'.repeat(10000);
+      const actual = replaceAllPolyfill('cd', 'ef', bigString);
+
+      assert.strictEqual(actual, expected);
+    });
+
+    specify('should curry', function() {
+      assert.strictEqual(replaceAllPolyfill('a', 'c', 'aba'), 'cbc');
+      assert.strictEqual(replaceAllPolyfill('a')('c', 'aba'), 'cbc');
+      assert.strictEqual(replaceAllPolyfill('a', 'c')('aba'), 'cbc');
+      assert.strictEqual(replaceAllPolyfill('a')('c')('aba'), 'cbc');
+    });
   });
 });
diff --git a/test/sign.js b/test/sign.js
index 4026bb9204..fccf103aed 100644
--- a/test/sign.js
+++ b/test/sign.js
@@ -87,7 +87,7 @@ describe('sign', function() {
   });
 
   context('signPolyfill', function() {
-    beforeEach(function() {
+    before(function() {
       if (RA.isNotFunction(Math.sign)) {
         this.skip();
       }
diff --git a/test/trimEnd.js b/test/trimEnd.js
index 17d8466294..de84cc942b 100644
--- a/test/trimEnd.js
+++ b/test/trimEnd.js
@@ -35,7 +35,7 @@ describe('trimEnd', function() {
   });
 
   context('trimEndInvoker', function() {
-    beforeEach(function() {
+    before(function() {
       if (RA.isNotFunction(String.prototype.trimEnd)) {
         this.skip();
       }
diff --git a/test/trimStart.js b/test/trimStart.js
index 7f5233a788..854103829b 100644
--- a/test/trimStart.js
+++ b/test/trimStart.js
@@ -38,7 +38,7 @@ describe('trimStart', function() {
   });
 
   context('trimStartInvoker', function() {
-    beforeEach(function() {
+    before(function() {
       if (RA.isNotFunction(String.prototype.trimStart)) {
         this.skip();
       }
diff --git a/test/trunc.js b/test/trunc.js
index 2aa47ff11f..f53323dff5 100644
--- a/test/trunc.js
+++ b/test/trunc.js
@@ -84,7 +84,7 @@ describe('trunc', function() {
   });
 
   context('truncPolyfill', function() {
-    beforeEach(function() {
+    before(function() {
       if (RA.isNotFunction(Math.trunc)) {
         this.skip();
       }
diff --git a/test/unzipObjWith.js b/test/unzipObjWith.js
new file mode 100644
index 0000000000..9e83519696
--- /dev/null
+++ b/test/unzipObjWith.js
@@ -0,0 +1,51 @@
+import { assert } from 'chai';
+import * as R from 'ramda';
+
+import * as RA from '../src';
+
+describe('unzipObjWith', function() {
+  it('should unzip an object into pair of lists', function() {
+    const fn = (value, key) => [key, { ...value, name: key }];
+    const obj = {
+      packageA: { version: '1.0.9' },
+      packageB: { version: '1.6.1' },
+      packageC: { version: '1.6.0' },
+    };
+
+    const actual = RA.unzipObjWith(fn, obj);
+
+    const expected = [
+      ['packageA', 'packageB', 'packageC'],
+      [
+        { name: 'packageA', version: '1.0.9' },
+        { name: 'packageB', version: '1.6.1' },
+        { name: 'packageC', version: '1.6.0' },
+      ],
+    ];
+
+    assert.deepEqual(actual, expected);
+  });
+
+  context('given empty object', function() {
+    specify('should return a pair of empty arrays', function() {
+      const fn = (value, key) => [key, value];
+      const obj = {};
+
+      const actual = RA.unzipObjWith(fn, obj);
+      const expected = [[], []];
+
+      assert.deepEqual(actual, expected);
+    });
+  });
+
+  it('should curry', function() {
+    const fn = (v, k) => [`new${k.toUpperCase()}`, 2 * v];
+    const obj = { a: 1, b: 2, c: 3 };
+    const expected = [['newA', 'newB', 'newC'], [2, 4, 6]];
+
+    assert.deepEqual(RA.unzipObjWith(fn, obj), expected);
+    assert.deepEqual(RA.unzipObjWith(fn)(obj), expected);
+    assert.deepEqual(RA.unzipObjWith()(fn)(obj), expected);
+    assert.deepEqual(RA.unzipObjWith(R.__, obj)(fn), expected);
+  });
+});
diff --git a/testem.json b/testem.json
index d0913d69a0..54d58e1142 100644
--- a/testem.json
+++ b/testem.json
@@ -1,13 +1,5 @@
 {
-  "framework": "mocha",
-  "cwd": ".",
-  "src_files": [
-    "src/*.js",
-    "test/*.js"
-  ],
-  "serve_files": [
-    "tmp-test-bundle.js"
-  ],
+  "test_page": "./test/mocha-testem.mustache",
   "before_tests": "npm run test:bundle-create",
   "after_tests": "npm run test:bundle-clean"
 }
diff --git a/types/test/padEnd.ts b/types/test/padEnd.ts
new file mode 100644
index 0000000000..e0616df01e
--- /dev/null
+++ b/types/test/padEnd.ts
@@ -0,0 +1,11 @@
+import * as RA from 'ramda-adjunct';
+
+RA.padEnd(3, 'a'); // $ExpectType string
+RA.padEnd(5)('abc'); // $ExpectType string
+RA.padEnd(10, 'hello'); // $ExpectType string
+
+RA.padEnd('10', 'afsd'); // $ExpectError
+RA.padEnd('12', 54); // $ExpectError
+RA.padEnd(null, 'a'); // $ExpectError
+RA.padEnd(undefined, 12); // $ExpectError
+RA.padEnd(undefined, 'abc'); // $ExpectError
diff --git a/types/test/unzipObjWith.ts b/types/test/unzipObjWith.ts
new file mode 100644
index 0000000000..db3ba4667e
--- /dev/null
+++ b/types/test/unzipObjWith.ts
@@ -0,0 +1,11 @@
+import * as RA from 'ramda-adjunct';
+
+RA.unzipObjWith((v, k) => [k, 1], { a: 1 }); // $ExpectType [string[], number[]]
+RA.unzipObjWith((v, k) => [2, 'hello'])({ a: 1 }); // $ExpectType [number[], string[]]
+RA.unzipObjWith((v, k) => [k, 1], {}); // $ExpectType [string[], number[]]
+RA.unzipObjWith<string, boolean, number>((v, k) => [true, 5], { a: 'b' }); // $ExpectType [boolean[], number[]]
+
+RA.unzipObjWith((v, k) => true, { a: 1 }); // $ExpectError
+RA.unzipObjWith((v, k) => [k, v], []); // $ExpectError
+RA.unzipObjWith<string, boolean, number>((v, k) => [k, v], { a: 'b' }); // $ExpectError
+RA.unzipObjWith((v, k) => [k, v], undefined); // $ExpectError