Repository: delvedor/find-my-way
Pull request #287 (2022-05-18 23:10:19)

Update hasConstraintStrategy method


Patch:
diff --git a/README.md b/README.md
index 1c7c51e..72de787 100644
--- a/README.md
+++ b/README.md
@@ -165,7 +165,7 @@ Constraints can be combined, and route handlers will only match if __all__ of th
 <a name="custom-constraint-strategies"></a>
 ### Custom Constraint Strategies
 
-Custom constraining strategies can be added and are matched against incoming requests while trying to maintain `find-my-way`'s high performance. To register a new type of constraint, you must add a new constraint strategy that knows how to match values to handlers, and that knows how to get the constraint value from a request. Register strategies when constructing a router or use the addCustomConstraintStrategy method.
+Custom constraining strategies can be added and are matched against incoming requests while trying to maintain `find-my-way`'s high performance. To register a new type of constraint, you must add a new constraint strategy that knows how to match values to handlers, and that knows how to get the constraint value from a request. Register strategies when constructing a router or use the addConstraintStrategy method.
 
 Add a custom constrain strategy when constructing a router:
 
@@ -192,7 +192,7 @@ const customResponseTypeStrategy = {
 const router = FindMyWay({ constraints: { accept: customResponseTypeStrategy } });
 ```
 
-Add a custom constraint strategy using the addCustomConstraintStrategy method:
+Add a custom constraint strategy using the addConstraintStrategy method:
 
 ```js
 const customResponseTypeStrategy = {
@@ -215,7 +215,7 @@ const customResponseTypeStrategy = {
 }
 
 const router = FindMyWay();
-router.addCustomConstraintStrategy(customResponseTypeStrategy);
+router.addConstraintStrategy(customResponseTypeStrategy);
 ```
 
 Once a custom constraint strategy is registered, routes can be added that are constrained using it:
diff --git a/index.d.ts b/index.d.ts
index 7f01d53..ccb439d 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -161,8 +161,8 @@ declare namespace Router {
     prettyPrint(): string;
     prettyPrint(opts: { commonPrefix?: boolean, includeMeta?: boolean | (string | symbol)[]  }): string;
 
-    hasCustomConstraintStrategy(strategyName: string): boolean;
-    addCustomConstraintStrategy(constraintStrategy: ConstraintStrategy<V>): void;
+    hasConstraintStrategy(strategyName: string): boolean;
+    addConstraintStrategy(constraintStrategy: ConstraintStrategy<V>): void;
 
     all: ShortHandRoute<V>;
 
diff --git a/index.js b/index.js
index 1aad974..654fabd 100644
--- a/index.js
+++ b/index.js
@@ -266,12 +266,12 @@ Router.prototype._on = function _on (method, path, opts, handler, store) {
   currentNode.handlerStorage.addHandler(handler, params, store, this.constrainer, constraints)
 }
 
-Router.prototype.hasCustomConstraintStrategy = function (strategyName) {
-  return this.constrainer.hasCustomConstraintStrategy(strategyName)
+Router.prototype.hasConstraintStrategy = function (strategyName) {
+  return this.constrainer.hasConstraintStrategy(strategyName)
 }
 
-Router.prototype.addCustomConstraintStrategy = function (constraints) {
-  this.constrainer.addCustomConstraintStrategy(constraints)
+Router.prototype.addConstraintStrategy = function (constraints) {
+  this.constrainer.addConstraintStrategy(constraints)
   this._rebuild(this.routes)
 }
 
diff --git a/lib/constrainer.js b/lib/constrainer.js
index 79f84c0..947fe3d 100644
--- a/lib/constrainer.js
+++ b/lib/constrainer.js
@@ -16,27 +16,30 @@ class Constrainer {
     // validate and optimize prototypes of given custom strategies
     if (customStrategies) {
       for (const strategy of Object.values(customStrategies)) {
-        this.addCustomConstraintStrategy(strategy)
+        this.addConstraintStrategy(strategy)
       }
     }
   }
 
-  hasCustomConstraintStrategy (strategyName) {
+  hasConstraintStrategy (strategyName) {
     const customConstraintStrategy = this.strategies[strategyName]
-    return customConstraintStrategy !== undefined && customConstraintStrategy.isCustom === true
+    if (customConstraintStrategy !== undefined) {
+      return customConstraintStrategy.isCustom || this.strategiesInUse.has(strategyName)
+    }
+    return false
   }
 
-  addCustomConstraintStrategy (strategy) {
+  addConstraintStrategy (strategy) {
     assert(typeof strategy.name === 'string' && strategy.name !== '', 'strategy.name is required.')
     assert(strategy.storage && typeof strategy.storage === 'function', 'strategy.storage function is required.')
     assert(strategy.deriveConstraint && typeof strategy.deriveConstraint === 'function', 'strategy.deriveConstraint function is required.')
 
-    if (this.hasCustomConstraintStrategy(strategy.name)) {
-      throw new Error(`There is already exists a custom constraint with the name ${strategy.name}.`)
+    if (this.strategies[strategy.name] && this.strategies[strategy.name].isCustom) {
+      throw new Error(`There already exists a custom constraint with the name ${strategy.name}.`)
     }
 
     if (this.strategiesInUse.has(strategy.name)) {
-      throw new Error(`There is already exists a route with ${strategy.name} constraint.`)
+      throw new Error(`There already exists a route with ${strategy.name} constraint.`)
     }
 
     strategy.isCustom = true


Test patch:
diff --git a/test/constraint.custom-versioning.test.js b/test/constraint.custom-versioning.test.js
index 67caf4a..e5559c1 100644
--- a/test/constraint.custom-versioning.test.js
+++ b/test/constraint.custom-versioning.test.js
@@ -42,7 +42,7 @@ test('A route could support multiple versions (find) / 1 (add strategy outside c
 
   const findMyWay = FindMyWay()
 
-  findMyWay.addCustomConstraintStrategy(customVersioning)
+  findMyWay.addConstraintStrategy(customVersioning)
 
   findMyWay.on('GET', '/', { constraints: { version: 'application/vnd.example.api+json;version=2' } }, noop)
   findMyWay.on('GET', '/', { constraints: { version: 'application/vnd.example.api+json;version=3' } }, noop)
@@ -84,7 +84,7 @@ test('Overriding default strategies uses the custom deriveConstraint function (a
 
   const findMyWay = FindMyWay()
 
-  findMyWay.addCustomConstraintStrategy(customVersioning)
+  findMyWay.addConstraintStrategy(customVersioning)
 
   findMyWay.on('GET', '/', { constraints: { version: 'application/vnd.example.api+json;version=2' } }, (req, res, params) => {
     t.equal(req.headers.accept, 'application/vnd.example.api+json;version=2')
@@ -111,9 +111,21 @@ test('Overriding custom strategies throws as error (add strategy outside constru
 
   const findMyWay = FindMyWay()
 
-  findMyWay.addCustomConstraintStrategy(customVersioning)
+  findMyWay.addConstraintStrategy(customVersioning)
 
-  t.throws(() => findMyWay.addCustomConstraintStrategy(customVersioning),
-    'There is already exists a custom constraint with the name version.'
+  t.throws(() => findMyWay.addConstraintStrategy(customVersioning),
+    'There already exists a custom constraint with the name version.'
+  )
+})
+
+test('Overriding default strategies after defining a route with constraint', t => {
+  t.plan(1)
+
+  const findMyWay = FindMyWay()
+
+  findMyWay.on('GET', '/', { constraints: { host: 'fastify.io', version: '1.0.0' } }, () => {})
+
+  t.throws(() => findMyWay.addConstraintStrategy(customVersioning),
+    'There already exists a route with version constraint.'
   )
 })
diff --git a/test/constraint.custom.test.js b/test/constraint.custom.test.js
index 9a0567f..f5e757d 100644
--- a/test/constraint.custom.test.js
+++ b/test/constraint.custom.test.js
@@ -42,7 +42,7 @@ test('A route could support a custom constraint strategy (add strategy outside c
 
   const findMyWay = FindMyWay()
 
-  findMyWay.addCustomConstraintStrategy(customHeaderConstraint)
+  findMyWay.addConstraintStrategy(customHeaderConstraint)
 
   findMyWay.on('GET', '/', { constraints: { requestedBy: 'curl' } }, alpha)
   findMyWay.on('GET', '/', { constraints: { requestedBy: 'wget' } }, beta)
@@ -79,7 +79,7 @@ test('A route could support a custom constraint strategy while versioned (add st
 
   const findMyWay = FindMyWay()
 
-  findMyWay.addCustomConstraintStrategy(customHeaderConstraint)
+  findMyWay.addConstraintStrategy(customHeaderConstraint)
 
   findMyWay.on('GET', '/', { constraints: { requestedBy: 'curl', version: '1.0.0' } }, alpha)
   findMyWay.on('GET', '/', { constraints: { requestedBy: 'curl', version: '2.0.0' } }, beta)
@@ -124,7 +124,7 @@ test('A route could support a custom constraint strategy while versioned and hos
 
   const findMyWay = FindMyWay()
 
-  findMyWay.addCustomConstraintStrategy(customHeaderConstraint)
+  findMyWay.addConstraintStrategy(customHeaderConstraint)
 
   findMyWay.on('GET', '/', { constraints: { requestedBy: 'curl', version: '1.0.0', host: 'fastify.io' } }, alpha)
   findMyWay.on('GET', '/', { constraints: { requestedBy: 'curl', version: '2.0.0', host: 'fastify.io' } }, beta)
@@ -171,7 +171,7 @@ test('Custom constraint strategies can set mustMatchWhenDerived flag to true whi
     }
   })
 
-  findMyWay.addCustomConstraintStrategy({
+  findMyWay.addConstraintStrategy({
     ...customHeaderConstraint,
     mustMatchWhenDerived: true
   })
@@ -212,7 +212,7 @@ test('Custom constraint strategies can set mustMatchWhenDerived flag to true whi
     }
   })
 
-  findMyWay.addCustomConstraintStrategy({
+  findMyWay.addConstraintStrategy({
     ...customHeaderConstraint,
     mustMatchWhenDerived: true
   })
@@ -253,7 +253,7 @@ test('Custom constraint strategies can set mustMatchWhenDerived flag to false wh
     }
   })
 
-  findMyWay.addCustomConstraintStrategy({
+  findMyWay.addConstraintStrategy({
     ...customHeaderConstraint,
     mustMatchWhenDerived: true
   })
@@ -264,14 +264,11 @@ test('Custom constraint strategies can set mustMatchWhenDerived flag to false wh
 })
 
 test('Has constraint strategy method test', t => {
-  t.plan(1)
+  t.plan(2)
 
-  const findMyWay = FindMyWay({
-    defaultRoute (req, res) {
-      t.pass()
-    }
-  })
+  const findMyWay = FindMyWay()
 
-  findMyWay.addCustomConstraintStrategy(customHeaderConstraint)
-  t.same(findMyWay.hasCustomConstraintStrategy(customHeaderConstraint.name), true)
+  t.same(findMyWay.hasConstraintStrategy(customHeaderConstraint.name), false)
+  findMyWay.addConstraintStrategy(customHeaderConstraint)
+  t.same(findMyWay.hasConstraintStrategy(customHeaderConstraint.name), true)
 })
diff --git a/test/constraints.test.js b/test/constraints.test.js
index 85cdad2..13124fc 100644
--- a/test/constraints.test.js
+++ b/test/constraints.test.js
@@ -90,10 +90,20 @@ test('Routes with multiple constraints are matched before routes with one constr
 })
 
 test('Has constraint strategy method test', t => {
-  t.plan(2)
+  t.plan(6)
 
   const findMyWay = FindMyWay()
 
-  t.same(findMyWay.hasCustomConstraintStrategy('version'), false)
-  t.same(findMyWay.hasCustomConstraintStrategy('host'), false)
+  t.same(findMyWay.hasConstraintStrategy('version'), false)
+  t.same(findMyWay.hasConstraintStrategy('host'), false)
+
+  findMyWay.on('GET', '/', { constraints: { host: 'fastify.io' } }, () => {})
+
+  t.same(findMyWay.hasConstraintStrategy('version'), false)
+  t.same(findMyWay.hasConstraintStrategy('host'), true)
+
+  findMyWay.on('GET', '/', { constraints: { host: 'fastify.io', version: '1.0.0' } }, () => {})
+
+  t.same(findMyWay.hasConstraintStrategy('version'), true)
+  t.same(findMyWay.hasConstraintStrategy('host'), true)
 })
diff --git a/test/types/router.test-d.ts b/test/types/router.test-d.ts
index e6ce153..43b6fdb 100644
--- a/test/types/router.test-d.ts
+++ b/test/types/router.test-d.ts
@@ -101,7 +101,7 @@ let http2Res!: Http2ServerResponse;
   expectType<void>(router.on('GET', '/', () => {}, {}))
   expectType<void>(router.on('GET', '/', { constraints: { version: '1.0.0' }}, () => {}, {}))
 
-  expectType<void>(router.addCustomConstraintStrategy(constraints.foo))
+  expectType<void>(router.addConstraintStrategy(constraints.foo))
 
   expectType<void>(router.get('/', () => {}))
   expectType<void>(router.get('/', { constraints: { version: '1.0.0' }}, () => {}))