Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QuickCheck Not Working #81

Open
bucklj4 opened this issue Aug 20, 2018 · 3 comments
Open

QuickCheck Not Working #81

bucklj4 opened this issue Aug 20, 2018 · 3 comments

Comments

@bucklj4
Copy link

bucklj4 commented Aug 20, 2018

Hi,

The QuickCheck button does not seem to be working as it should. In particular whenever I click it, I get the following VS error message: VS Code can't execute this file. Check the terminal. In the terminal, I see type c:\Users\%USER%\.vscode\extensions\ucl.haskelly-0.5.4\ad39fbca-d904-42a7-92bf-b7e66c5a895a.txt -------- Error -------- Error: ENOENT: no such file or directory, open 'c:\Users\%USER%\Documents\e49dcfb1-2bb0-4677-9758-d82bee8cb210.hs'------------------------

@Maxez
Copy link

Maxez commented Jan 28, 2019

I got annoyed by the QuickCheck button not working so I decided to fix it. Here is my solution (tested on Windows 10, fully modified file is attached at the end of the post):

  1. We need to modify testCode.js file in Haskelly installation directory (in my case the file was located at C:\Users\YourUsername\.vscode\extensions\ucl.haskelly-0.5.5\out\src\helpers\testCode.js). Open it in a text editor.
  2. There is a bug in testHaskellFile function. In case of a non-stack project we want to create a copy of the original haskell source code, remove main function from it and add code that runs the tests. The original code asynchronously creates the copy and reads from it. We want to start reading AFTER the copy is finished. Replace line 136
    fs.createReadStream(filePath).pipe(fs.createWriteStream(newPath));
    with this
let writer = fs.createWriteStream(newPath);
fs.createReadStream(filePath).pipe(writer);

then place the reading code inside this

writer.once('finish', () => {
    //here goes the reading
     fs.readFile(newPath...
});

This way we ensure that we read the file once we finished copying.
3. There is also a problem with main function removal part. The original code expects the main function to be at the end of a source code file and that there will be no main function type declaration. Here is my improved version of removeMainFunction function:

function removeMultilineComments(data) {
    return data.replace(/{-[\s\S]*?-}/g, (comment) => {
        return comment.replace(/\S/g, ' ');
    });
}
function removeMainFunction(data) {
    const main_decl_regex = /^main\s*::.*$/m;
    const main_def_regex = /^main\s*=.*$/m;
    const comment_regex = /^\s*--.*$/m;
    const other_regex = /^\S+.*$/m;
    const dataArray = removeMultilineComments(data).split('\n');
    let decl_start;
    let decl_end;
    let def_start;
    let def_end;
    for (let i = 0; i < dataArray.length; i++) {
    	//main type signature
    	if (main_decl_regex.test(dataArray[i])) {
        	if (def_start !== undefined && def_end === undefined) {
            	def_end = i;
            }
            if (decl_start === undefined) {
                decl_start = i;
            }
        }
        //main definition
        else if (main_def_regex.test(dataArray[i])) {
        	if (decl_start !== undefined && decl_end === undefined) {
        		decl_end = i;
            }
        	if (def_start === undefined) {
        		def_start = i;
            }
        }
        //skip comments
        else if (comment_regex.test(dataArray[i])) {
        	//do nothing
        }
        //different expression/declaration
        else if (other_regex.test(dataArray[i])) {
        	if (decl_start !== undefined && decl_end === undefined) {
            	decl_end = i;
            }
            if (def_start !== undefined && def_end === undefined) {
            	def_end = i;
            }
        }
    }
    if (decl_start !== undefined && decl_end === undefined) {
    	decl_end = dataArray.length;
    }
    if (def_start !== undefined && def_end === undefined) {
    	def_end = dataArray.length;
    }

    return dataArray.filter((value, index, arr) => {
    	return (decl_start === undefined || index < decl_start || index >= decl_end) &&
        	   (def_start === undefined || index < def_start || index >= def_end);
    }).join('\n');
}

That's it. Worked for me. You can find modified testCode.js here (it's packed as .zip):
testCode.zip

@martrik
Copy link
Collaborator

martrik commented Jan 30, 2019

Hello @Maxez, thanks a lot for your contribution! Would you mind opening a PR with your change so that your contribution is recorded and I can formally merge it? Thanks again!

@Maxez
Copy link

Maxez commented Jan 30, 2019

Hi @martrik. I created the PR with my changes (I modified testCode.ts file from which I guess the testCode.js is generated). Please verify it since I'm not a JS programmer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants