Last active
February 13, 2017 04:25
-
-
Save okunishinishi/60ec3f8a610afdd8d3b8cd39d5b59659 to your computer and use it in GitHub Desktop.
[SUGOS] チュートリアル04 - Moduleをnpmパッケージ化する ref: http://qiita.com/okunishinishi@github/items/2c5f4f5fbd57fbb7c3e2
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
# Install as global module | |
npm install -g sugo-scaffold | |
# Show version to check if the installation succeeded | |
sugo-scaffold --version |
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
# Create a module project | |
sugo-scaffold module "sugos-tutorial-04" | |
cd sugos-tutorial-04 | |
npm install | |
npm test |
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
// Example JavasScript, after ES2015 | |
function doSomething (src, dest, options = {}) { | |
let { | |
force = false, | |
mkdirp = true | |
} = options | |
console.log('Do something with args: ', src, dest, force) | |
} | |
doSomething('foo.txt', 'bar.txt', { force: false, mkdirp: false }) |
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
// Example JavasScript, before ES2015 | |
function doSomething (src, dest, options) { | |
if(typeof options === 'undefined') { | |
options = {} | |
} | |
var force = typeof options.force === 'undefined' ? false : options.force | |
var mkdirp = typeof options.mkdirp === 'undefined' ? true : options.mkdirp | |
console.log('Do something with args: ', src, dest, force) | |
} | |
doSomething('foo.txt', 'bar.txt', { force: false, mkdirp: false }) |
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
/** | |
* KeyValueStore class | |
* @class KeyValueStore | |
* @augments Module | |
* @param {Object} config - Configuration | |
*/ | |
'use strict' | |
const { Module } = require('sugo-module-base') | |
const { name, version, description } = require('../package.json') | |
const co = require('co') | |
const { hasBin } = require('sg-check') | |
const debug = require('debug')('sugo:module:demo-module') | |
/** @lends KeyValueStore */ | |
class KeyValueStore extends Module { | |
constructor (config = {}) { | |
debug('Config: ', config) | |
super(config) | |
} | |
/** | |
* Ping a message. | |
* @param {string} pong | |
* @returns {Promise.<string>} - Pong message | |
*/ | |
ping (pong = 'pong') { | |
return co(function * pingAck () { | |
return pong // Return result to a remote caller. | |
}) | |
} | |
/** | |
* Assert actor system requirements. | |
* @throws {Error} - System requirements failed error | |
* @returns {Promise.<boolean>} - Asserted state | |
*/ | |
assert () { | |
const bins = [ 'node' ] // Required commands | |
return co(function * assertAck () { | |
yield hasBin.assertAll(bins) | |
return true | |
}) | |
} | |
/** | |
* Module specification | |
* @see https://github.com/realglobe-Inc/sg-schemas/blob/master/lib/module_spec.json | |
*/ | |
get $spec () { | |
return { | |
name, | |
version, | |
desc: description, | |
methods: { | |
ping: { | |
desc: 'Test the reachability of a module.', | |
params: [ | |
{ name: 'pong', type: 'string', desc: 'Pong message to return' } | |
], | |
return: { | |
type: 'string', | |
desc: 'Pong message' | |
} | |
}, | |
assert: { | |
desc: 'Test if the actor fulfills system requirements', | |
params: [], | |
throws: [ { | |
type: 'Error', | |
desc: 'System requirements failed' | |
} ], | |
return: { | |
type: 'boolean', | |
desc: 'System is OK' | |
} | |
} | |
}, | |
events: null | |
} | |
} | |
} | |
module.exports = KeyValueStore | |
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
/** ... */ | |
'use strict' | |
const { Module } = require('sugo-module-base') | |
const { name, version, description } = require('../package.json') | |
const co = require('co') | |
const fs = require('fs') | |
const { hasBin } = require('sg-check') | |
const debug = require('debug')('sugo:module:demo-module') | |
/** @lends KeyValueStore */ | |
class KeyValueStore extends Module { | |
// Add "filename" parameter on constructor | |
constructor (config = {}) { | |
let { filename = 'kv.json' } = config | |
debug('Config: ', config) | |
super(config) | |
const s = this | |
s.filename = filename | |
} | |
/** ... */ | |
ping (pong = 'pong') { /* ... */ } | |
/** ... */ | |
assert () { /* ... */ } | |
// Define methods for Key-vale store | |
set (key, value) { | |
const s = this | |
return co(function * () { | |
let data = yield s._read().catch(() => ({})) | |
data[ key ] = value | |
return yield s._write(data) | |
}) | |
} | |
get (key) { | |
const s = this | |
return co(function * () { | |
let data = yield s._read() | |
return data[ key ] | |
}) | |
} | |
del (key) { | |
const s = this | |
return co(function * () { | |
let data = yield s._read() | |
delete data[ key ] | |
return yield s._write(data) | |
}) | |
} | |
// Private function to read data file | |
// Methods with "_" is not exposed to remote caller | |
_read () { | |
let { filename } = this | |
return new Promise((resolve, reject) => | |
fs.readFile((filename), (err, content) => err ? reject(err) : resolve(content)) | |
).then(JSON.parse) | |
} | |
// Private function to write data file | |
// Methods with "_" is not exposed to remote caller | |
_write (data) { | |
let { filename } = this | |
return new Promise((resolve, reject) => | |
fs.writeFile(filename, JSON.stringify(data), (err) => err ? reject(err) : resolve()) | |
) | |
} | |
/** ... */ | |
get $spec () { /* ... */ } | |
} | |
module.exports = KeyValueStore | |
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
/** ... */ | |
'use strict' | |
const { Module } = require('sugo-module-base') | |
const { name, version, description } = require('../package.json') | |
const co = require('co') | |
const fs = require('fs') | |
const { hasBin } = require('sg-check') | |
const debug = require('debug')('sugo:module:demo-module') | |
/** @lends KeyValueStore */ | |
class KeyValueStore extends Module { | |
constructor (config = {}) { /* ... */ } | |
/** ... */ | |
ping (pong = 'pong') { /* ... */ } | |
/** ... */ | |
assert () { /* ... */ } | |
set (key, value) { /* ... */ } | |
get (key) { /* ... */ } | |
del (key) { /* ... */ } | |
// Private function to read data file | |
// Methods with "_" is not exposed to remote caller | |
_read () { /* ... */ } | |
// Private function to write data file | |
// Methods with "_" is not exposed to remote caller | |
_write (data) { /* ... */ } | |
/** | |
* Module specification | |
* @see https://github.com/realglobe-Inc/sg-schemas/blob/master/lib/module_spec.json | |
*/ | |
get $spec () { | |
return { | |
name, | |
version, | |
desc: description, | |
methods: { | |
ping: { /* ... */ }, | |
assert: { /* ... */ }, | |
set: { | |
desc: 'Set key value', | |
params: [ | |
{ name: 'key', type: 'string', desc: 'Key to set' }, | |
{ name: 'value', type: 'string', desc: 'value to set' } | |
] | |
}, | |
get: { | |
desc: 'Get by key ', | |
params: [ | |
{ name: 'key', type: 'string', desc: 'Key to set' } | |
], | |
return: { type: 'string', desc: 'Found value' } | |
}, | |
del: { | |
desc: 'Delete by key ', | |
params: [ | |
{ name: 'key', type: 'string', desc: 'Key to set' } | |
] | |
} | |
}, | |
events: null | |
} | |
} | |
} | |
module.exports = KeyValueStore | |
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
/** | |
* Test case for demoModule. | |
* Runs with mocha. | |
*/ | |
'use strict' | |
const KeyValueStore = require('../lib/key_value_store.js') | |
const assert = require('assert') | |
const co = require('co') | |
const { EventEmitter } = require('events') | |
const sgSchemas = require('sg-schemas') | |
const sgValidator = require('sg-validator') | |
describe('demo-module', function () { | |
this.timeout(3000) | |
before(() => co(function * () { | |
})) | |
after(() => co(function * () { | |
})) | |
it('Get module spec', () => co(function * () { | |
let module = new KeyValueStore({ $emitter: new EventEmitter() }) | |
assert.ok(module) | |
let { $spec } = module | |
let specError = sgValidator(sgSchemas.moduleSpec).validate($spec) | |
assert.ok(!specError) | |
})) | |
it('Try ping-pong', () => co(function * () { | |
let module = new KeyValueStore({ $emitter: new EventEmitter() }) | |
let pong = yield module.ping('pong') | |
assert.equal(pong, 'pong') | |
})) | |
it('Do assert', () => co(function * () { | |
let module = new KeyValueStore({ $emitter: new EventEmitter() }) | |
let caught | |
try { | |
yield module.assert({}) | |
} catch (err) { | |
caught = err | |
} | |
assert.ok(!caught) | |
})) | |
it('Compare methods with spec', () => co(function * () { | |
let module = new KeyValueStore({ $emitter: new EventEmitter() }) | |
let { $spec } = module | |
let implemented = Object.getOwnPropertyNames(KeyValueStore.prototype) | |
.filter((name) => !/^[\$_]/.test(name)) | |
.filter((name) => !~[ 'constructor' ].indexOf(name)) | |
let described = Object.keys($spec.methods).filter((name) => !/^[\$_]/.test(name)) | |
for (let name of implemented) { | |
assert.ok(!!~described.indexOf(name), `${name} method should be described in spec`) | |
} | |
for (let name of described) { | |
assert.ok(!!~implemented.indexOf(name), `${name} method should be implemented`) | |
} | |
})) | |
}) | |
/* global describe, before, after, it */ | |
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
/** | |
* Test case for demoModule. | |
* Runs with mocha. | |
*/ | |
'use strict' | |
const KeyValueStore = require('../lib/key_value_store.js') | |
const assert = require('assert') | |
const co = require('co') | |
const { EventEmitter } = require('events') | |
const sgSchemas = require('sg-schemas') | |
const sgValidator = require('sg-validator') | |
describe('demo-module', function () { | |
this.timeout(3000) | |
before(() => co(function * () { | |
})) | |
after(() => co(function * () { | |
})) | |
it('Get module spec', () => co(function * () { /* ... */ })) | |
it('Try ping-pong', () => co(function * () { /* ... */ })) | |
it('Do assert', () => co(function * () { /* ... */ })) | |
it('Compare methods with spec', () => co(function * () { /* ... */ })) | |
it('Do get/set/del', () => co(function * () { | |
let module = new KeyValueStore({ | |
filename: `${__dirname}/../testing-store.json`, | |
$emitter: new EventEmitter() | |
}) | |
yield module.set('foo', 'This is foo') | |
{ | |
let foo = yield module.get('foo') | |
assert.equal(foo, 'This is foo') | |
} | |
yield module.del('foo') | |
{ | |
let foo = yield module.get('foo') | |
assert.equal(foo, undefined) | |
} | |
})) | |
}) | |
/* global describe, before, after, it */ | |
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
npm test |
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
#!/usr/bin/env node | |
/** | |
* Example usage to register module on actor | |
* @see https://github.com/realglobe-Inc/sugo-actor | |
*/ | |
'use strict' | |
const { KeyValueStore } = require('sugos-tutorial-04') | |
const sugoActor = require('sugo-actor') | |
const co = require('co') | |
co(function * () { | |
let actor = sugoActor('http://my-sugo-cloud.example.com/actors', { | |
key: 'my-actor-01', | |
modules: { | |
// Register the module | |
kvs: new KeyValueStore({ | |
filename: 'kv.json' | |
}) | |
} | |
}) | |
yield actor.connect() | |
}).catch((err) => console.error(err)) | |
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
# Keyword-arguments example of Python | |
def do_something(src, dest, **keywords): | |
force = keywords.pop('force', false) | |
mkdirp = keywords.pop('mkdirp', true) | |
print('Do something with args: ', src, dest, force) | |
do_something('foo.txt', 'bar.txt', force=false, mkdirp=false) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment