-
Notifications
You must be signed in to change notification settings - Fork 78
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Add option to import examples from libraries. Closes #1993 * Add error handling * Add built files to codeclimate ignore * move generated files to build dir * Add tests for upload library models plugin * Add test asset
- Loading branch information
Showing
13 changed files
with
439 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
src/plugins/UploadLibraryModelToBlob/UploadLibraryModelToBlob.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/*globals define*/ | ||
|
||
define([ | ||
'text!./metadata.json', | ||
'plugin/PluginBase', | ||
'fs', | ||
'../../visualizers/panels/ForgeActionButton/Libraries.json', | ||
], function ( | ||
pluginMetadata, | ||
PluginBase, | ||
fs, | ||
Libraries, | ||
) { | ||
'use strict'; | ||
|
||
const fsp = fs.promises; | ||
pluginMetadata = JSON.parse(pluginMetadata); | ||
|
||
class UploadLibraryModelToBlob extends PluginBase { | ||
constructor(libraries=Libraries) { | ||
super(); | ||
this.pluginMetadata = pluginMetadata; | ||
this.libraries = libraries; | ||
} | ||
|
||
async main(/*callback*/) { | ||
const config = this.getCurrentConfig(); | ||
const {libraryName, modelName} = config; | ||
const hash = await this.uploadLibraryModel(libraryName, modelName); | ||
this.createMessage(this.rootNode, hash); | ||
this.result.setSuccess(true); | ||
//callback(null, this.result); | ||
} | ||
|
||
async uploadLibraryModel(libraryName, modelName) { | ||
const data = await fsp.readFile(this.getLibraryModelPath(libraryName, modelName)); | ||
const hash = await this.blobClient.putFile(`${modelName}.webgmexm`, data); | ||
return hash; | ||
} | ||
|
||
getLibraryModelPath(libraryName, modelName) { | ||
const modelInfo = this.getLibraryModelInfo(libraryName, modelName); | ||
return modelInfo.path; | ||
} | ||
|
||
getLibraryModelInfo(libraryName, modelName) { | ||
const libraryInfo = this.libraries.find(libraryInfo => libraryInfo.name === libraryName); | ||
if (!libraryInfo) { | ||
throw new Error(`Library not found: ${libraryName}`); | ||
} | ||
const modelInfo = libraryInfo.models.find(modelInfo => modelInfo.name === modelName); | ||
if (!modelInfo) { | ||
throw new Error(`Model not found in ${libraryName}: ${modelName}`); | ||
} | ||
return modelInfo; | ||
} | ||
} | ||
|
||
UploadLibraryModelToBlob.metadata = pluginMetadata; | ||
|
||
return UploadLibraryModelToBlob; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"id": "UploadLibraryModelToBlob", | ||
"name": "UploadLibraryModelToBlob", | ||
"version": "0.1.0", | ||
"description": "", | ||
"icon": { | ||
"class": "glyphicon glyphicon-cog", | ||
"src": "" | ||
}, | ||
"disableServerSideExecution": false, | ||
"disableBrowserSideExecution": false, | ||
"dependencies": [], | ||
"writeAccessRequired": false, | ||
"configStructure": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
src/visualizers/panels/ForgeActionButton/ExamplesDialog.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<script> | ||
let element; | ||
export let examples = []; | ||
export let jquery; | ||
export let client; | ||
import { onMount } from 'svelte'; | ||
onMount(() => jquery(element).modal('show')); | ||
export function destroy() { | ||
jquery(element).modal('hide'); | ||
} | ||
export function events() { | ||
return element; | ||
} | ||
async function importExample(example) { | ||
const event = new CustomEvent('importExample', {detail: example}); | ||
element.dispatchEvent(event); | ||
} | ||
</script> | ||
|
||
<div bind:this={element} class="examples-modal modal fade in" tabindex="-1" role="dialog"> | ||
<div class="modal-dialog modal-lg"> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<button type="button" class="close" on:click|stopPropagation|preventDefault={destroy}>x</button> | ||
<span class="title">Available Examples</span> | ||
</div> | ||
<div class="modal-body"> | ||
<div> | ||
<table class="table highlight"> | ||
<thead> | ||
<tr> | ||
<th >Name</th> | ||
<th >Library</th> | ||
<th >Description</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{#each examples as example} | ||
<tr> | ||
<td>{example.name}</td> | ||
<td>{example.library}</td> | ||
<td class="description">{example.description}</td> | ||
<!-- TODO: add loading icon? --> | ||
<td on:click|stopPropagation|preventDefault={() => importExample(example)}><i class="material-icons">get_app</i></td> | ||
</tr> | ||
{/each} | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<style> | ||
.description { | ||
font-style: italic; | ||
} | ||
.title { | ||
font-size: 28px; | ||
vertical-align: middle; | ||
} | ||
.examples-modal th { | ||
text-align: left; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
src/visualizers/panels/ForgeActionButton/build/ExamplesDialog.js
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
1 change: 1 addition & 0 deletions
1
src/visualizers/panels/ForgeActionButton/build/ExamplesDialog.js.map
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file not shown.
105 changes: 105 additions & 0 deletions
105
test/unit/plugins/UploadLibraryModelToBlob/UploadLibraryModelToBlob.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/*eslint-env node, mocha*/ | ||
/** | ||
* Generated by PluginGenerator 2.20.5 from webgme on Thu Feb 11 2021 12:20:02 GMT-0600 (Central Standard Time). | ||
*/ | ||
|
||
const testFixture = require('../../../globals'); | ||
|
||
describe('UploadLibraryModelToBlob', function () { | ||
const gmeConfig = testFixture.getGmeConfig(); | ||
const logger = testFixture.logger.fork('UploadLibraryModelToBlob'); | ||
const PluginCliManager = testFixture.WebGME.PluginCliManager; | ||
|
||
const assert = require('assert'); | ||
const {promisify} = require('util'); | ||
const manager = new PluginCliManager(null, logger, gmeConfig); | ||
const pluginName = 'UploadLibraryModelToBlob'; | ||
const projectName = 'testProject'; | ||
const PIPELINES = '/f'; | ||
manager.executePlugin = promisify(manager.executePlugin); | ||
manager.runPluginMain = promisify(manager.runPluginMain); | ||
let context, | ||
gmeAuth, | ||
storage; | ||
|
||
before(async function () { | ||
gmeAuth = await testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName); | ||
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth); | ||
await storage.openDatabase(); | ||
const importParam = { | ||
projectSeed: testFixture.path.join(testFixture.DF_SEED_DIR, 'devProject', 'devProject.webgmex'), | ||
projectName: projectName, | ||
branchName: 'master', | ||
logger: logger, | ||
gmeConfig: gmeConfig | ||
}; | ||
|
||
const importResult = await testFixture.importProject(storage, importParam); | ||
const {project, commitHash} = importResult; | ||
await project.createBranch('test', commitHash); | ||
context = { | ||
project: project, | ||
commitHash: commitHash, | ||
branchName: 'test', | ||
activeNode: PIPELINES, | ||
namespace: 'pipeline', | ||
}; | ||
|
||
}); | ||
|
||
after(async function () { | ||
await storage.closeDatabase(); | ||
await gmeAuth.unload(); | ||
}); | ||
|
||
it('should return the hash in the first message', async function () { | ||
const plugin = await manager.initializePlugin(pluginName); | ||
plugin.libraries = [{ | ||
name: 'testlib', | ||
models: [{ | ||
name: 'TestOperation', | ||
path: 'test/assets/TestOperation.webgmexm' | ||
}] | ||
}]; | ||
const pluginConfig = { | ||
libraryName: 'testlib', | ||
modelName: 'TestOperation', | ||
}; | ||
await manager.configurePlugin(plugin, pluginConfig, context); | ||
const {messages} = await manager.runPluginMain(plugin); | ||
assert.equal(messages.length, 1); | ||
assert.equal(messages[0].message.length, 40); | ||
const alphnum = /^[a-z0-9]+$/; | ||
assert(alphnum.test(messages[0].message)); | ||
}); | ||
|
||
it('should throw error if library not found', async function () { | ||
const plugin = await manager.initializePlugin(pluginName); | ||
const pluginConfig = { | ||
libraryName: 'IDontExist', | ||
modelName: 'unused', | ||
}; | ||
await manager.configurePlugin(plugin, pluginConfig, context); | ||
await assert.rejects( | ||
() => manager.runPluginMain(plugin), | ||
/Library not found/ | ||
); | ||
}); | ||
|
||
it('should throw error if model not found', async function () { | ||
const plugin = await manager.initializePlugin(pluginName); | ||
plugin.libraries = [{ | ||
name: 'testlib', | ||
models: [] | ||
}]; | ||
const pluginConfig = { | ||
libraryName: 'testlib', | ||
modelName: 'unused', | ||
}; | ||
await manager.configurePlugin(plugin, pluginConfig, context); | ||
await assert.rejects( | ||
() => manager.runPluginMain(plugin), | ||
/Model not found/ | ||
); | ||
}); | ||
}); |
Oops, something went wrong.