Browse Source

fix: do not override value when set another one to the middle

e22m4u 1 year ago
parent
commit
b15d37259d
3 changed files with 85 additions and 32 deletions
  1. 17 11
      dist/cjs/index.cjs
  2. 31 21
      src/path-trie.js
  3. 37 0
      src/path-trie.spec.js

+ 17 - 11
dist/cjs/index.cjs

@@ -134,19 +134,25 @@ var _PathTrie = class _PathTrie {
         "Invalid index %v has passed to the PathTrie._createNode.",
         index
       );
-    const isLast = tokens.length - 1 === index;
     let child = parent.children[token];
-    if (isLast && child != null) {
-      debug("The node %v already exist.", token);
-      if (child.value == null) {
-        child.value = value;
-      } else if (child.value !== value) {
-        throw new import_js_format2.Errorf(
-          "The duplicate path %v has a different value.",
-          "/" + tokens.join("/")
-        );
+    const isLast = tokens.length - 1 === index;
+    if (child) {
+      if (!isLast) {
+        debug("The node %v already exist.", token);
+        return this._createNode(tokens, index + 1, value, child);
+      } else {
+        debug("The node %v already exist.", token);
+        if (child.value == null) {
+          debug("The node %v has the same value.", token);
+          child.value = value;
+        } else if (child.value !== value) {
+          throw new import_js_format2.Errorf(
+            "The duplicate path %v has a different value.",
+            "/" + tokens.join("/")
+          );
+        }
+        return child;
       }
-      return child;
     }
     debug("The node %v does not exist.", token);
     child = {

+ 31 - 21
src/path-trie.js

@@ -123,30 +123,40 @@ export class PathTrie {
         'Invalid index %v has passed to the PathTrie._createNode.',
         index,
       );
-    // если добавляемый узел является последним,
-    // а его токен уже существует, то проверяем
-    // наличие значения в существующем узле
-    const isLast = tokens.length - 1 === index;
+    // проверка существования узла
+    // по текущему токену
     let child = parent.children[token];
-    if (isLast && child != null) {
-      debug('The node %v already exist.', token);
-      // если существующий узел не имеет
-      // значения, то устанавливаем
-      if (child.value == null) {
-        child.value = value;
+    const isLast = tokens.length - 1 === index;
+    if (child) {
+      // если узел не является последним,
+      // то переходим к следующему
+      if (!isLast) {
+        debug('The node %v already exist.', token);
+        return this._createNode(tokens, index + 1, value, child);
       }
-      // если существующий узел имеет значение
-      // отличное от устанавливаемого,
-      // то выбрасываем ошибку
-      else if (child.value !== value) {
-        throw new Errorf(
-          'The duplicate path %v has a different value.',
-          '/' + tokens.join('/'),
-        );
+      // если узел является последним,
+      // то проверяем наличие значения
+      else {
+        debug('The node %v already exist.', token);
+        // если существующий узел не имеет
+        // значения, то устанавливаем текущее
+        if (child.value == null) {
+          debug('The node %v has the same value.', token);
+          child.value = value;
+        }
+        // если существующий узел имеет
+        // значение отличное от текущего,
+        // то выбрасываем ошибку
+        else if (child.value !== value) {
+          throw new Errorf(
+            'The duplicate path %v has a different value.',
+            '/' + tokens.join('/'),
+          );
+        }
+        // так как данный токен является последним,
+        // то возвращаем существующий узел
+        return child;
       }
-      // так как данный токен является последним,
-      // то возвращаем существующий узел
-      return child;
     }
     debug('The node %v does not exist.', token);
     // создаем новый узел, и если токен является

+ 37 - 0
src/path-trie.spec.js

@@ -227,6 +227,43 @@ describe('PathTrie', function () {
           'but no parameters found in the path "/:".',
       );
     });
+
+    it('does not overrides value when set another one to the middle', function () {
+      const trie = new PathTrie();
+      trie.add('/foo/bar/baz', VALUE);
+      trie.add('/foo/bar', ANOTHER_VALUE);
+      expect(trie['_root']).to.be.eql({
+        token: '',
+        regexp: undefined,
+        names: [],
+        value: undefined,
+        children: {
+          foo: {
+            token: 'foo',
+            regexp: undefined,
+            names: [],
+            value: undefined,
+            children: {
+              bar: {
+                token: 'bar',
+                regexp: undefined,
+                names: [],
+                value: ANOTHER_VALUE,
+                children: {
+                  baz: {
+                    token: 'baz',
+                    regexp: undefined,
+                    names: [],
+                    value: VALUE,
+                    children: {},
+                  },
+                },
+              },
+            },
+          },
+        },
+      });
+    });
   });
 
   describe('match', function () {