Browse Source

Refactor: improve `fileEqual` impl

SukkaW 1 year ago
parent
commit
e13cee4e46
2 changed files with 33 additions and 50 deletions
  1. 14 2
      Build/lib/create-file.test.ts
  2. 19 48
      Build/lib/create-file.ts

+ 14 - 2
Build/lib/create-file.test.ts

@@ -39,6 +39,12 @@ describe('fileEqual', () => {
     false
     false
   ));
   ));
 
 
+  it('comment less', () => test(
+    ['# A', '# B', 'B'],
+    ['# A', 'B'],
+    false
+  ));
+
   it('larger', () => test(
   it('larger', () => test(
     ['A', 'B'],
     ['A', 'B'],
     ['A', 'B', 'C'],
     ['A', 'B', 'C'],
@@ -51,9 +57,15 @@ describe('fileEqual', () => {
     false
     false
   ));
   ));
 
 
-  it('eol', () => test(
+  it('eol more', () => test(
     ['A', 'B'],
     ['A', 'B'],
     ['A', 'B', ''],
     ['A', 'B', ''],
-    true
+    false
+  ));
+
+  it('eol less', () => test(
+    ['A', 'B', ''],
+    ['A', 'B'],
+    false
   ));
   ));
 });
 });

+ 19 - 48
Build/lib/create-file.ts

@@ -11,75 +11,46 @@ export async function fileEqual(linesA: string[], source: AsyncIterable<string>
     return false;
     return false;
   }
   }
 
 
-  const linesABound = linesA.length - 1;
-
+  const maxIndexA = linesA.length - 1;
   let index = -1;
   let index = -1;
 
 
-  let aLen = 0;
-  let bLen = 0;
-
   for await (const lineB of source) {
   for await (const lineB of source) {
     index++;
     index++;
 
 
-    if (index > linesABound) {
-      return (index === linesA.length && lineB.length === 0);
-    }
-
-    const lineA = linesA[index];
-    aLen = lineA.length;
-    bLen = lineB.length;
-
-    if (aLen === 0) {
-      if (bLen === 0) {
-        // both lines are empty, check next line
-        continue;
-      }
-      // lineA is empty but lineB is not
-      return false;
-    }
-    // now lineA can not be empty
-    if (bLen === 0) {
-      // lineB is empty but lineA is not
+    if (index > maxIndexA) {
       return false;
       return false;
     }
     }
 
 
-    // now both lines can not be empty
+    const lineA = linesA[index];
 
 
-    const firstCharA = lineA.charCodeAt(0);
-    const firstCharB = lineB.charCodeAt(0);
+    const lineAIsComment = isCommentLine(lineA);
+    const lineBIsComment = isCommentLine(lineB);
 
 
-    if (firstCharA !== firstCharB) {
+    if (lineAIsComment !== lineBIsComment) {
       return false;
       return false;
     }
     }
 
 
-    // now firstCharA is equal to firstCharB, we only need to check the first char
-    if (firstCharA === 35 /* # */) {
-      continue;
-    }
-    // adguard conf
-    if (firstCharA === 33 /* ! */) {
-      continue;
-    }
-
-    if (
-      firstCharA === 47 /* / */
-      && lineA[1] === '/' && lineB[1] === '/'
-      && lineA[3] === '#' && lineB[3] === '#'
-    ) {
+    // Now both line are either both comment or both not comment
+    // We only need to compare one of them
+    if (lineAIsComment) {
       continue;
       continue;
     }
     }
 
 
-    if (aLen !== bLen) {
-      return false;
-    }
-
     if (lineA !== lineB) {
     if (lineA !== lineB) {
       return false;
       return false;
     }
     }
   }
   }
 
 
-  // The file becomes larger
-  return !(index < linesABound);
+  return index === maxIndexA;
+}
+
+export function isCommentLine(line: string): boolean {
+  const firstChar = line.charCodeAt(0);
+  return (
+    firstChar === 35 // #
+    || firstChar === 33 // !
+    || (firstChar === 47 && line[1] === '/' && line[3] === '#') // //##
+  );
 }
 }
 
 
 export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string) {
 export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string) {