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

Run validation code after every draw loop #22267

Merged
merged 6 commits into from May 10, 2018
Merged

Conversation

balderdash
Copy link
Contributor

@balderdash balderdash commented May 8, 2018

Adds a field for validation code on the gamelab editor page:
image

This snippet of code is run at the end of every draw loop. If the validation code calls levelSucess(), the success dialog will pop up and you can continue to the next level. I also hide the 'finish' button on any levels with validation code.

I got started with failure "validation", but we need to switch to CSF-style topinstructions before we can display failure feeback.

@balderdash balderdash requested a review from joshlory May 8, 2018 22:48
Copy link
Contributor

@joshlory joshlory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM for a first pass at validation.

Now would be a great time to establish some norms about ownership of these success functions, and who's on point to fix them when they break. There's a sort-of-scary future where we are afraid of making any API changes because we think we may break validation on some levels, but we don't know which ones (and have no way to test except manually one by one).

__validationState = null;
__validationResult = null;
${this.level.validationCode}
ret = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the magic ret come from?

Copy link
Contributor Author

@balderdash balderdash May 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I was trying to workaround a bug in our intepreter (or rather the acorn parser?) that appears to choke on bare objects used as standalone expressions. Updated to wrap the code in a function and properly return the value I care about.

function levelSuccess(testResult) {
__validationState = 'succeeded';
__validationResult = testResult;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I auto-pass any level with the following code? 😄

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should catch you with this line just before the validation code runs:

__validationState = null;

Though if you try to use __validationState in your program it'll get reset every tick. The task of adding more reserved keywords becomes ever more pressing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, makes sense. What does configuring additional reserved words look like? Will we need upstream support from https://github.com/NeilFraser/JS-Interpreter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure we can handle it at the blockly code generation layer by adding "reserved words":
https://github.com/code-dot-org/blockly/blob/00b15c2a78946cdd7d17e808a594c99a6b54bb68/core/code_generation/generator.js#L299-L306

This will then generate slightly different variable names if you try to make a variable name that collides with a reserved word:
https://github.com/code-dot-org/blockly/blob/00b15c2a78946cdd7d17e808a594c99a6b54bb68/core/code_generation/names.js#L110-L131

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, it looks like we're already doing this! Maybe add these as reserved words, and remove the double-underscore?

// Add to reserved word list: API, local variables in execution evironment
// (execute) and the infinite loop detection function.
Blockly.JavaScript.addReservedWords('GameLab,code');

= f.label 'Validation code'
%p
This is a snippet of javascript that is run after every draw loop. Call levelSuccess() in here to stop the level as a success. You can also pass a number into levelSuccess() to give the student a non-perfect test result (see <a href="https://github.com/code-dot-org/code-dot-org/blob/101fbfd2dcdd635d7359e991559ba782f9fd00be/apps/src/constants.js#L33-L106">TestResults</a> for the list of valid test results).
= f.text_area :validation_code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is our API contract with level builders? If they depend on internal behavior, and we change internal behavior, who owns fixing?

Who is responsible for keeping the code working, and testing it after deploys?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, but I have a couple thoughts:

  • Ideally levelbuilders will only use standard Gamelab properties and methods (which are stable anyway), and things specifically provided by ValidationSetup. We can add accessors to ValidationSetup for things exposed by the helper library for when levelbuilders need to inspect things like behaviors.
  • Unless we programmatically prevent access to helper library methods and properties, I suspect levelbuilders will wind up using them anyway, and my instinct is that it would be very difficult to stop them programmatically.

Copy link
Contributor

@joshlory joshlory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tagging @ryansloan to make sure we don't lose track of this question:

What is our API contract with level builders?

@balderdash balderdash merged commit 9bcce43 into staging May 10, 2018
@ryansloan
Copy link
Contributor

@joshlory @balderdash I will add API contract question to Curriculum/Product agenda for our next meeting.

Also, yay validation!

@balderdash
Copy link
Contributor Author

@balderdash balderdash deleted the gamelab-validation branch May 18, 2018 23:54
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

Successfully merging this pull request may close these issues.

None yet

3 participants