Ver código fonte

Updated test files for vscode and plugin

Diana Arreola 4 anos atrás
pai
commit
4364324786

+ 1 - 1
extension/ext-plugin/.gitignore

@@ -1,4 +1,4 @@
-plugin.js
+out/
 node_modules/
 
 

+ 127 - 53
extension/ext-plugin/package-lock.json

@@ -14,44 +14,44 @@
       }
     },
     "@babel/generator": {
-      "version": "7.10.3",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.3.tgz",
-      "integrity": "sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA==",
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz",
+      "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.10.3",
+        "@babel/types": "^7.10.4",
         "jsesc": "^2.5.1",
         "lodash": "^4.17.13",
         "source-map": "^0.5.0"
       }
     },
     "@babel/helper-function-name": {
-      "version": "7.10.3",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz",
-      "integrity": "sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw==",
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+      "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-get-function-arity": "^7.10.3",
-        "@babel/template": "^7.10.3",
-        "@babel/types": "^7.10.3"
+        "@babel/helper-get-function-arity": "^7.10.4",
+        "@babel/template": "^7.10.4",
+        "@babel/types": "^7.10.4"
       }
     },
     "@babel/helper-get-function-arity": {
-      "version": "7.10.3",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz",
-      "integrity": "sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg==",
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+      "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.10.3"
+        "@babel/types": "^7.10.4"
       }
     },
     "@babel/helper-split-export-declaration": {
-      "version": "7.10.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz",
-      "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==",
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz",
+      "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.10.1"
+        "@babel/types": "^7.10.4"
       }
     },
     "@babel/helper-validator-identifier": {
@@ -85,39 +85,115 @@
       }
     },
     "@babel/parser": {
-      "version": "7.10.3",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.3.tgz",
-      "integrity": "sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA==",
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz",
+      "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==",
       "dev": true
     },
     "@babel/template": {
-      "version": "7.10.3",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.3.tgz",
-      "integrity": "sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA==",
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+      "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.10.3",
-        "@babel/parser": "^7.10.3",
-        "@babel/types": "^7.10.3"
+        "@babel/code-frame": "^7.10.4",
+        "@babel/parser": "^7.10.4",
+        "@babel/types": "^7.10.4"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.10.4",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+          "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.10.4"
+          }
+        },
+        "@babel/helper-validator-identifier": {
+          "version": "7.10.4",
+          "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+          "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+          "dev": true
+        },
+        "@babel/highlight": {
+          "version": "7.10.4",
+          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+          "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-validator-identifier": "^7.10.4",
+            "chalk": "^2.0.0",
+            "js-tokens": "^4.0.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        }
       }
     },
     "@babel/traverse": {
-      "version": "7.10.3",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.3.tgz",
-      "integrity": "sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug==",
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz",
+      "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.10.3",
-        "@babel/generator": "^7.10.3",
-        "@babel/helper-function-name": "^7.10.3",
-        "@babel/helper-split-export-declaration": "^7.10.1",
-        "@babel/parser": "^7.10.3",
-        "@babel/types": "^7.10.3",
+        "@babel/code-frame": "^7.10.4",
+        "@babel/generator": "^7.10.4",
+        "@babel/helper-function-name": "^7.10.4",
+        "@babel/helper-split-export-declaration": "^7.10.4",
+        "@babel/parser": "^7.10.4",
+        "@babel/types": "^7.10.4",
         "debug": "^4.1.0",
         "globals": "^11.1.0",
         "lodash": "^4.17.13"
       },
       "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.10.4",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+          "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.10.4"
+          }
+        },
+        "@babel/helper-validator-identifier": {
+          "version": "7.10.4",
+          "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+          "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+          "dev": true
+        },
+        "@babel/highlight": {
+          "version": "7.10.4",
+          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+          "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-validator-identifier": "^7.10.4",
+            "chalk": "^2.0.0",
+            "js-tokens": "^4.0.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
         "globals": {
           "version": "11.12.0",
           "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
@@ -127,14 +203,22 @@
       }
     },
     "@babel/types": {
-      "version": "7.10.3",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz",
-      "integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==",
+      "version": "7.10.4",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz",
+      "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==",
       "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.10.3",
+        "@babel/helper-validator-identifier": "^7.10.4",
         "lodash": "^4.17.13",
         "to-fast-properties": "^2.0.0"
+      },
+      "dependencies": {
+        "@babel/helper-validator-identifier": {
+          "version": "7.10.4",
+          "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+          "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+          "dev": true
+        }
       }
     },
     "@types/chai": {
@@ -1718,16 +1802,6 @@
           "requires": {
             "isexe": "^2.0.0"
           }
-        },
-        "yargs-parser": {
-          "version": "13.0.0",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz",
-          "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==",
-          "dev": true,
-          "requires": {
-            "camelcase": "^5.0.0",
-            "decamelize": "^1.2.0"
-          }
         }
       }
     },
@@ -2677,9 +2751,9 @@
       }
     },
     "yargs-parser": {
-      "version": "13.1.2",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
-      "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+      "version": "13.0.0",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz",
+      "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==",
       "dev": true,
       "requires": {
         "camelcase": "^5.0.0",

+ 2 - 1
extension/ext-plugin/package.json

@@ -4,7 +4,8 @@
   "description": "",
   "main": "plugin.js",
   "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1",
+    "test": "cross-env TS_NODE_FILES=true mocha --exit --require ts-node/register --colors src/test/**/*.ts",
+    
     "lint": "eslint . --ext .ts"
   },
   "keywords": [],

+ 15 - 15
extension/ext-plugin/plugin.ts → extension/ext-plugin/src/plugin.ts

@@ -13,7 +13,7 @@ interface CallBack {
   (howdoiOutput: string): void
 }
 
-function main(arg: string): void {
+export function main(arg: string): void {
   const userCommand: string = arg
   const userCommandWithoutComment: string[]|null = modifyCommentedText(userCommand)
     
@@ -31,9 +31,9 @@ function main(arg: string): void {
   }   
 }
 
-async function spawnChild(command: string, callbackFunc: CallBack): Promise<void> {
+export async function spawnChild(command: string, callbackFunc: CallBack): Promise<void> {
   const commandWithoutPrefix = removeHowdoiPrefix(command)
-  const process = await cp.spawn('howdoi', [commandWithoutPrefix, '-n 3'])
+  const process = await cp.spawn(HOWDOI_PREFIX, [commandWithoutPrefix, '-n 3'])
   let howdoiCommandOutput = ''
   process.stdout.on('data', (data: Buffer) => {
     howdoiCommandOutput += String(data)
@@ -53,42 +53,42 @@ async function spawnChild(command: string, callbackFunc: CallBack): Promise<void
   })
 }
 
-function removeHowdoiPrefix(command: string): string {
+export function removeHowdoiPrefix(command: string): string {
   if (!command.trim().startsWith(HOWDOI_PREFIX)) {
-    return command
+    return command.trim()
   }
-  return command.replace(HOWDOI_PREFIX, '')
+  return command.replace(HOWDOI_PREFIX, '').trim()
 }
 
-function modifyCommentedText(userCommand: string): string[]|null {
+export function modifyCommentedText(userCommand: string): string[]|null {
   /* This function finds the comment regex, removes it from the string and returns an array 
   with the modified string, the beginning comment regex, ending comment regex */
-  const frontCommentRegex =  /^[!@#<>/%*(+=._-]+/
+  const frontCommentRegex =  /^[!@#<>/;%*(+=._-]+/
   const endCommentRegex = /[!@#<>/%*+=._-]+$/
   let frontCommentChar: string
   let endCommentChar: string
   let userCommandWithoutComment: string[]
   const initialMatchRegex: RegExpMatchArray | null = userCommand.match(frontCommentRegex)
-  const endMatchRegex: RegExpMatchArray | null = userCommand.match(frontCommentRegex)
+  const endMatchRegex: RegExpMatchArray | null = userCommand.match(endCommentRegex)
         
   if (initialMatchRegex && endMatchRegex){
     frontCommentChar = initialMatchRegex.join()
     endCommentChar = endMatchRegex.join()
     userCommand = userCommand.replace(frontCommentRegex, '')
     userCommand = userCommand.replace(endCommentRegex, '')
-    userCommandWithoutComment = [userCommand, frontCommentChar, endCommentChar]
+    userCommandWithoutComment = [userCommand.trim(), frontCommentChar, endCommentChar]
     return userCommandWithoutComment
   }
   else if(endMatchRegex){
     endCommentChar = endMatchRegex.join()
     userCommand = userCommand.replace(endCommentRegex, '')
-    userCommandWithoutComment = [userCommand, '', endCommentChar]
+    userCommandWithoutComment = [userCommand.trim(), '', endCommentChar]
     return userCommandWithoutComment
   }
   else if(initialMatchRegex){
     frontCommentChar = initialMatchRegex.join()
     userCommand= userCommand.replace(frontCommentRegex, '')
-    userCommandWithoutComment = [userCommand, frontCommentChar, '']
+    userCommandWithoutComment = [userCommand.trim(), frontCommentChar, '']
     return userCommandWithoutComment
   }
   else {
@@ -96,7 +96,7 @@ function modifyCommentedText(userCommand: string): string[]|null {
   }
 }
 
-function organizeHowdoiOutput(howdoiOutput: string, frontCommentChar: string, endCommentChar: string): string[][] {
+export function organizeHowdoiOutput(howdoiOutput: string, frontCommentChar: string, endCommentChar: string): string[][] {
   /* Creates an array from the howdoiOutput string in which each element 
   is one of three answers from the usersCommand */
   const delim = '\n'+'================================================================================' + '\n' + '\n'
@@ -112,7 +112,7 @@ function organizeHowdoiOutput(howdoiOutput: string, frontCommentChar: string, en
   return newHowdoiAnswersArr
 }
 
-function createHowdoiResult(howdoiResultArr: string[][], userCommand: string): HowdoiResult {
+export function createHowdoiResult(howdoiResultArr: string[][], userCommand: string): HowdoiResult {
   const howdoiResultObj: HowdoiResult = {question: userCommand, answer: [], link: []}
 
   for (let i = 0; i < howdoiResultArr.length; i++) {
@@ -123,7 +123,7 @@ function createHowdoiResult(howdoiResultArr: string[][], userCommand: string): H
   return howdoiResultObj
 }
 
-function howdoi(howdoiOutput: string, userCommand: string, frontCommentChar: string, endCommentChar: string): HowdoiResult {
+export function howdoi(howdoiOutput: string, userCommand: string, frontCommentChar: string, endCommentChar: string): HowdoiResult {
   const organizedHowdoiArr: string[][] = organizeHowdoiOutput(howdoiOutput, frontCommentChar, endCommentChar)
   const howdoiResultObj: HowdoiResult = createHowdoiResult(organizedHowdoiArr, userCommand)
   return howdoiResultObj

+ 58 - 0
extension/ext-plugin/src/test/plugin.test.ts

@@ -0,0 +1,58 @@
+import { assert} from 'chai'
+import 'mocha'
+import * as myExtension from '../plugin'
+
+describe('Plugin Tests', function () {
+  describe('#removeHowdoiPrefix test', function () {
+    it('test 1', function () {
+      assert.equal(myExtension.removeHowdoiPrefix('howdoi query'), 'query')
+    })
+    it('test 2', function () {
+      assert.equal(myExtension.removeHowdoiPrefix(' howdoi query '), 'query')
+    })
+    it('test 3', function () {
+      assert.equal(myExtension.removeHowdoiPrefix('query'), 'query')
+    })
+    it('test 4', function () {
+      assert.equal(myExtension.removeHowdoiPrefix(' query '), 'query')
+    })
+  })
+  describe('#modifyCommentedText test', function () {
+    it('test 1', function () {
+      // null
+      assert.equal(myExtension.modifyCommentedText('howdoi query'), null)
+    })
+    it('test 2', function () {
+      // JS, TS, C/ C++/ C#, Java, GO, Rust, Scala, Swift, J#, Dlang single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('// howdoi query'), ['howdoi query', '//', ''])
+      assert.deepEqual(myExtension.modifyCommentedText('//howdoi query'), ['howdoi query', '//', ''])
+    })
+    it('test 3', function () {
+      // Python, Ruby, powershell, Julia, R, prolog, Crystal, Dockerfile, Diff single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('# howdoi query'), ['howdoi query', '#', ''] )
+      assert.deepEqual(myExtension.modifyCommentedText('#howdoi query'), ['howdoi query', '#', ''] )
+    })
+    it('test 4', function () {
+      // C++, CSS single line comment 
+      assert.deepEqual(myExtension.modifyCommentedText('/* howdoi query */'), ['howdoi query', '/*', '*/'] )
+    })
+    it('test 5', function () {
+      // HTML, PHP, Markdown, Vue single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('<!-- howdoi query -->'), ['howdoi query', '<!--', '-->'] )
+    })
+    it('test 6', function () {
+      // SQL, Haskell single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('-- howdoi query'), ['howdoi query', '--', ''] )
+    })
+    it('test 7', function () {
+      // LaTex single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('% howdoi query'), ['howdoi query', '%', ''] )
+    })
+    it('test 8', function () {
+      // clojure single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('; howdoi query'), ['howdoi query', ';', ''] ) 
+    })
+  })
+})
+
+  

+ 3 - 1
extension/ext-plugin/tsconfig.json

@@ -1,9 +1,11 @@
 {
   "compilerOptions": {
     "target": "es2018",                       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
-    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
+    "module": "commonjs", 
+    "outDir": "out",                    /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
     "lib": ["es2018", "dom"],                             /* Specify library files to be included in the compilation. */
     "sourceMap": true,                     /* Generates corresponding '.map' file. */
+    "rootDir": "src",
     "strict": true,                           /* Enable all strict type-checking options. */
     "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
     "skipLibCheck": true,                     /* Skip type checking of declaration files. */

+ 3 - 1
extension/vscode-howdoi/.gitignore

@@ -1,2 +1,4 @@
 node_modules/
-out/
+out/
+.vscode/**
+.vscode-test/**

+ 0 - 1
extension/vscode-howdoi/.vscodeignore

@@ -3,7 +3,6 @@
 out/test/**
 src/**
 .gitignore
-vsc-extension-quickstart.md
 **/tsconfig.json
 **/.eslintrc.json
 **/*.map

+ 17 - 15
extension/vscode-howdoi/src/extension.ts

@@ -13,9 +13,9 @@ interface CallBack {
   (howdoiOutput: string): void
 }
 
-async function spawnChild(command: string, callbackFunc: CallBack): Promise<void> {
+export async function spawnChild(command: string, callbackFunc: CallBack): Promise<void> {
   const commandWithoutPrefix = removeHowdoiPrefix(command)
-  const process = await cp.spawn('howdoi', [commandWithoutPrefix, '-n 3'])
+  const process = await cp.spawn(HOWDOI_PREFIX, [commandWithoutPrefix, '-n 3'])
   let howdoiCommandOutput: string = ''
 
   process.stdout.on('data', (data: Buffer) => {
@@ -36,42 +36,42 @@ async function spawnChild(command: string, callbackFunc: CallBack): Promise<void
   })
 }
 
-function removeHowdoiPrefix(command: string): string {
+export function removeHowdoiPrefix(command: string): string {
   if (!command.trim().startsWith(HOWDOI_PREFIX)) {
-    return command
+    return command.trim()
   }
-  return command.replace(HOWDOI_PREFIX, '')
+  return command.replace(HOWDOI_PREFIX, '').trim()
 }
 
-function modifyCommentedText(userCommand: string): string[]|null {
+export function modifyCommentedText(userCommand: string): string[]|null {
   /* This function finds the comment regex, removes it from the string and returns an array
   with the modified string, the beginning comment regex, ending comment regex */
-  const frontCommentRegex = /^[!@#<>/%*(+=._-]+/
+  const frontCommentRegex = /^[!@#<>/;%*(+=._-]+/
   const endCommentRegex = /[!@#<>/%*+=._-]+$/
   let frontCommentChar: string
   let endCommentChar: string
   let userCommandWithoutComment: string[]
   const initialMatchRegex: RegExpMatchArray | null = userCommand.match(frontCommentRegex)
-  const endMatchRegex: RegExpMatchArray | null = userCommand.match(frontCommentRegex)
+  const endMatchRegex: RegExpMatchArray | null = userCommand.match(endCommentRegex)
 
   if (initialMatchRegex && endMatchRegex){
     frontCommentChar = initialMatchRegex.join()
     endCommentChar = endMatchRegex.join()
     userCommand = userCommand.replace(frontCommentRegex, '')
     userCommand = userCommand.replace(endCommentRegex, '')
-    userCommandWithoutComment = [userCommand, frontCommentChar, endCommentChar]
+    userCommandWithoutComment = [userCommand.trim(), frontCommentChar, endCommentChar]
     return userCommandWithoutComment
   }
   else if(endMatchRegex){
     endCommentChar = endMatchRegex.join()
     userCommand = userCommand.replace(endCommentRegex, '')
-    userCommandWithoutComment = [userCommand, '', endCommentChar]
+    userCommandWithoutComment = [userCommand.trim(), '', endCommentChar]
     return userCommandWithoutComment
   }
   else if(initialMatchRegex){
     frontCommentChar = initialMatchRegex.join()
     userCommand= userCommand.replace(frontCommentRegex, '')
-    userCommandWithoutComment = [userCommand, frontCommentChar, '']
+    userCommandWithoutComment = [userCommand.trim(), frontCommentChar, '']
     return userCommandWithoutComment
   }
   else {
@@ -79,7 +79,7 @@ function modifyCommentedText(userCommand: string): string[]|null {
   }
 }
 
-function organizeHowdoiOutput(howdoiOutput: string, frontCommentChar: string, endCommentChar: string): string[][] {
+export function organizeHowdoiOutput(howdoiOutput: string, frontCommentChar: string, endCommentChar: string): string[][] {
   /* Creates an array from the howdoiOutput string in which each element
   is one of three answers from the usersCommand */
   const delim = '\n'+'================================================================================'+'\n'+'\n'
@@ -94,7 +94,7 @@ function organizeHowdoiOutput(howdoiOutput: string, frontCommentChar: string, en
   return newHowdoiAnswersArr
 }
 
-function createHowdoiResult(howdoiResultArr: string[][], userCommand: string): HowdoiResult {
+export function createHowdoiResult(howdoiResultArr: string[][], userCommand: string): HowdoiResult {
   let howdoiResultObj: HowdoiResult = {question: userCommand, answer: [], link: []}
 
   for (let i = 0; i < howdoiResultArr.length; i++) {
@@ -105,13 +105,13 @@ function createHowdoiResult(howdoiResultArr: string[][], userCommand: string): H
   return howdoiResultObj
 }
 
-function howdoi(howdoiOutput: string, userCommand: string, frontCommentChar: string, endCommentChar: string): HowdoiResult {
+export function howdoi(howdoiOutput: string, userCommand: string, frontCommentChar: string, endCommentChar: string): HowdoiResult {
   const organizedHowdoiArr: string[][] = organizeHowdoiOutput(howdoiOutput, frontCommentChar, endCommentChar)
   const howdoiResultObj: HowdoiResult = createHowdoiResult(organizedHowdoiArr, userCommand)
   return howdoiResultObj
 }
 
-function quickPicker(editor: any, howdoiResultObj: HowdoiResult, userCommand: string): void {
+export function quickPicker(editor: any, howdoiResultObj: HowdoiResult, userCommand: string): void {
   const quickPick = vscode.window.createQuickPick()
 
   quickPick.items = howdoiResultObj.answer.map((answer: any) => (
@@ -148,8 +148,10 @@ export function activate(context: vscode.ExtensionContext) {
       const endCommentChar: string = userCommandWithoutComment[2]
 
       const callbackFunc: CallBack = function(howdoiOutput: string): void {
+        
         let howdoiResultObj = howdoi(howdoiOutput, userCommand, frontCommentChar, endCommentChar)
         quickPicker(editor, howdoiResultObj, userCommand)
+      
       }
 
       spawnChild(textToBeSearched, callbackFunc)

+ 53 - 4
extension/vscode-howdoi/src/test/suite/extension.test.ts

@@ -1,11 +1,60 @@
 import * as assert from 'assert'
 import * as vscode from 'vscode'
-// import * as myExtension from '../../extension';
+import * as Mocha from 'mocha'
+import * as myExtension from '../../extension'
 
 suite('Extension Test Suite', () => {
   vscode.window.showInformationMessage('Start all tests.')
-  test('Sample test', () => {
-    assert.equal(-1, [1, 2, 3].indexOf(5))
-    assert.equal(-1, [1, 2, 3].indexOf(0))
+  suite('removeHowdoiPrefix test', () => {
+    test('test 1', function () {
+      assert.equal(myExtension.removeHowdoiPrefix('howdoi query'), 'query')
+    })
+    test('test 2', function () {
+      assert.equal(myExtension.removeHowdoiPrefix(' howdoi query '), 'query')
+    })
+    test('test 3', function () {
+      assert.equal(myExtension.removeHowdoiPrefix('query'), 'query')
+    })
+    test('test 4', function () {
+      assert.equal(myExtension.removeHowdoiPrefix(' query '), 'query')
+    })
+
+  })
+  suite('modifyCommentedText test', () => {
+
+    test('test 1', function () {
+      // null
+      assert.equal(myExtension.modifyCommentedText('howdoi query'), null)
+    })
+    test('test 2', function () {
+      // JS, TS, C/ C++/ C#, Java, GO, Rust, Scala, Swift, J#, Dlang single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('// howdoi query'), ['howdoi query', '//', ''])
+      assert.deepEqual(myExtension.modifyCommentedText('//howdoi query'), ['howdoi query', '//', ''])
+    })
+    test('test 3', function () {
+      // Python, Ruby, powershell, Julia, R, prolog, Crystal, Dockerfile, Diff single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('# howdoi query'), ['howdoi query', '#', ''] )
+      assert.deepEqual(myExtension.modifyCommentedText('#howdoi query'), ['howdoi query', '#', ''] )
+    })
+    test('test 4', function () {
+      // C++, CSS single line comment 
+      assert.deepEqual(myExtension.modifyCommentedText('/* howdoi query */'), ['howdoi query', '/*', '*/'] )
+    })
+    test('test 5', function () {
+      // HTML, PHP, Markdown, Vue single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('<!-- howdoi query -->'), ['howdoi query', '<!--', '-->'] )
+    })
+    test('test 6', function () {
+      // SQL, Haskell single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('-- howdoi query'), ['howdoi query', '--', ''] )
+    })
+    test('test 7', function () {
+      // LaTex single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('% howdoi query'), ['howdoi query', '%', ''] )
+    })
+    test('test 8', function () {
+      // clojure single line comment
+      assert.deepEqual(myExtension.modifyCommentedText('; howdoi query'), ['howdoi query', ';', ''] ) 
+    }) 
   })
 })