mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-01 03:16:56 -05:00
144 lines
4.9 KiB
CoffeeScript
144 lines
4.9 KiB
CoffeeScript
utils = require 'core/utils'
|
|
|
|
RootView = require 'views/core/RootView'
|
|
template = require 'templates/editor/verifier/verifier-view'
|
|
VerifierTest = require './VerifierTest'
|
|
SuperModel = require 'models/SuperModel'
|
|
Campaigns = require 'collections/Campaigns'
|
|
Level = require 'models/Level'
|
|
|
|
module.exports = class VerifierView extends RootView
|
|
className: 'style-flat'
|
|
template: template
|
|
id: 'verifier-view'
|
|
|
|
events:
|
|
'click #go-button': 'onClickGoButton'
|
|
|
|
constructor: (options, @levelID) ->
|
|
super options
|
|
# TODO: sort tests by unexpected result first
|
|
@passed = 0
|
|
@failed = 0
|
|
@problem = 0
|
|
@testCount = 0
|
|
|
|
defaultCores = 2
|
|
@cores = Math.max(window.navigator.hardwareConcurrency, defaultCores)
|
|
@careAboutFrames = true
|
|
|
|
if @levelID
|
|
@levelIDs = [@levelID]
|
|
@testLanguages = ['python', 'javascript', 'java', 'lua', 'coffeescript']
|
|
@cores = 1
|
|
@startTestingLevels()
|
|
else
|
|
@campaigns = new Campaigns()
|
|
@supermodel.trackRequest @campaigns.fetch(data: {project: 'slug,type,levels'})
|
|
@campaigns.comparator = (m) ->
|
|
['intro', 'course-2', 'course-3', 'course-4', 'course-5', 'course-6', 'course-8',
|
|
'dungeon', 'forest', 'desert', 'mountain', 'glacier', 'volcano'].indexOf(m.get('slug'))
|
|
|
|
onLoaded: ->
|
|
super()
|
|
return if @levelID
|
|
@filterCampaigns()
|
|
@filterCodeLanguages()
|
|
@render()
|
|
|
|
filterCampaigns: ->
|
|
@levelsByCampaign = {}
|
|
for campaign in @campaigns.models when campaign.get('type') in ['course', 'hero'] and campaign.get('slug') isnt 'picoctf'
|
|
@levelsByCampaign[campaign.get('slug')] ?= {levels: [], checked: true}
|
|
campaignInfo = @levelsByCampaign[campaign.get('slug')]
|
|
for levelID, level of campaign.get('levels') when level.type not in ['hero-ladder', 'course-ladder', 'game-dev', 'web-dev'] # Would use isType, but it's not a Level model
|
|
campaignInfo.levels.push level.slug
|
|
|
|
filterCodeLanguages: ->
|
|
defaultLanguages = utils.getQueryVariable('languages', 'python,javascript').split(/, ?/)
|
|
@codeLanguages ?= ({id: c, checked: c in defaultLanguages} for c in ['python', 'javascript', 'java', 'lua', 'coffeescript'])
|
|
|
|
onClickGoButton: (e) ->
|
|
@filterCampaigns()
|
|
@levelIDs = []
|
|
@careAboutFrames = @$("#careAboutFrames").is(':checked')
|
|
@cores = @$("#cores").val()|0
|
|
for campaign, campaignInfo of @levelsByCampaign
|
|
if @$("#campaign-#{campaign}-checkbox").is(':checked')
|
|
for level in campaignInfo.levels
|
|
@levelIDs.push level unless level in @levelIDs
|
|
else
|
|
campaignInfo.checked = false
|
|
@testLanguages = []
|
|
for codeLanguage in @codeLanguages
|
|
if @$("#code-language-#{codeLanguage.id}-checkbox").is(':checked')
|
|
codeLanguage.checked = true
|
|
@testLanguages.push codeLanguage.id
|
|
else
|
|
codeLanguage.checked = false
|
|
@startTestingLevels()
|
|
|
|
startTestingLevels: ->
|
|
@levelsToLoad = @initialLevelsToLoad = @levelIDs.length
|
|
for levelID in @levelIDs
|
|
level = @supermodel.getModel(Level, levelID) or new Level _id: levelID
|
|
if level.loaded
|
|
@onLevelLoaded()
|
|
else
|
|
@listenToOnce @supermodel.loadModel(level).model, 'sync', @onLevelLoaded
|
|
|
|
onLevelLoaded: (level) ->
|
|
if --@levelsToLoad is 0
|
|
@onTestLevelsLoaded()
|
|
else
|
|
@render()
|
|
|
|
onTestLevelsLoaded: ->
|
|
|
|
@linksQueryString = window.location.search
|
|
#supermodel = if @levelID then @supermodel else undefined
|
|
@tests = []
|
|
@tasksList = []
|
|
for levelID in @levelIDs
|
|
level = @supermodel.getModel(Level, levelID)
|
|
solutions = level?.getSolutions()
|
|
for codeLanguage in @testLanguages
|
|
if not solutions or _.find(solutions, language: codeLanguage)
|
|
@tasksList.push level: levelID, language: codeLanguage
|
|
|
|
@testCount = @tasksList.length
|
|
console.log("Starting in", @cores, "cores...")
|
|
chunks = _.groupBy @tasksList, (v,i) => i%@cores
|
|
supermodels = [@supermodel]
|
|
|
|
_.forEach chunks, (chunk, i) =>
|
|
_.delay =>
|
|
parentSuperModel = supermodels[supermodels.length-1]
|
|
chunkSupermodel = new SuperModel()
|
|
chunkSupermodel.models = _.clone parentSuperModel.models
|
|
chunkSupermodel.collections = _.clone parentSuperModel.collections
|
|
supermodels.push chunkSupermodel
|
|
|
|
async.eachSeries chunk, (task, next) =>
|
|
test = new VerifierTest task.level, (e) =>
|
|
@update(e)
|
|
if e.state in ['complete', 'error', 'no-solution']
|
|
if e.state is 'complete'
|
|
if test.isSuccessful()
|
|
++@passed
|
|
else
|
|
++@failed
|
|
else if e.state is 'no-solution'
|
|
--@testCount
|
|
else
|
|
++@problem
|
|
|
|
next()
|
|
, chunkSupermodel, task.language, {dontCareAboutFrames: not @careAboutFrames}
|
|
@tests.unshift test
|
|
@render()
|
|
, => @render()
|
|
, if i > 0 then 5000 + i * 1000 else 0
|
|
|
|
update: (event) =>
|
|
@render()
|