Skip to content

Commit

Permalink
Preparing for 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
etki committed Feb 17, 2017
1 parent 5140438 commit f2f9ef0
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .istanbul.yml
Expand Up @@ -12,7 +12,7 @@ instrumentation:
complete-copy: false
save-baseline: false
baseline-file: ./report/coverage/coverage-baseline.json
include-all-sources: false
include-all-sources: true
include-pid: false
es-modules: false
reporting:
Expand Down
14 changes: 14 additions & 0 deletions .npmignore
@@ -0,0 +1,14 @@
# Node files
npm-debug.log
node_modules
report

# IDE files
.idea

# CI files
.travis.yml
.istanbul.yml

# Other
.gitignore
7 changes: 7 additions & 0 deletions .travis.yml
Expand Up @@ -5,6 +5,13 @@ before_script: npm i
script:
- npm test
- npm run test:coverage
deploy:
provider: npm
email: dev@amagroup.ru
api_key:
secure: gIgsuqVCVq/c8xNeyvA0mbMC3eye4G57vVmhMitNmjOYi0UodlR/cLiYWeR7pIE2vuFe1W07igX5CcOSs/MS0YrpGq54ddqdg/cUVPtPWcN2zzLGKC8m7d4l3CVAvJNoZyNNkfPT/PS+ZHc9lHtg28zPdy//wkIF5NtfDpPIbcXYLXulZ1JFhKp0fAIArLNyPHLqw12nYnLXNztCP+bFVFVyceE+TysfAzFMMkmBmGMmCyk5UVk9oWEL0bdTco4MfF8jx64gFc6Gq8nfvb7GrM23J8HhGKunwrQOAcJXUspfDRXhUOuZ2qIpn1+YAlKFm7RNlSFBiKvKCFWGWUIIngaZrXweFbOoqPeM4BXuXtHksymWMcpwVbchX5Ep02eryyf0QvpIEp9KM0uJp88yEYGL62u6rKjwmV4fArJybUhJ2qOFO86dpJtkwn2k1cZjYahttJmHPpOEDvONBPcyBRwLUhsMy7dTcyAAbv/3ACKdLba1AXUmhXpeQi/N5uRsvwbjt6h0VeZWDhRDKqZhreVo3drjq7KRBfkRfLxFJWASOPznNZYJ2d4gzXL0wwDObds8H4BTCN23lUCPZ1ZiCr3x7QVPdLEmC1ldi+Br0+PgFVhIL3MAycL9toXrjiyerUD6SNkVT1+hhqrvUhInyDpY9F/I74QnYZQWqvKCBCg=
on:
tags: true
env:
global:
secure: BzR0z6qUPG2JZrEE9EMcjpqw9aO7wtvk6/O4EaYldXHmGBt1oi8CFOS5EaXsY44isYC+DnngLBU6A03Io7b+19oUJroPiZ+1eF9gHCZvllEWG9i/PMnvSQ2pLCSSm2KxNlymKkCJ64iNdkWw6DbZlVeCfn2Zpc4er4KKFeaC3OuajhdpHHo4Ogn3azqIAl+H9RYUq3XgUBblTuF9Q1qSqvY5Z37Z4ibdy5N9ASLwsEzcFrXJjvoT+yG0fmmeyLs6YqI2B/CcMfzDdujt3YF3AP0qEu3RsonPePgaQkFMXgQWJWock+Hv6EyeSSjAEKbYXgs1lB2iubw2bGUJid5N2uLUqmdjP8m2xCKXvHJiOPtDHnc0BGk7VLe/5dL9/cGT4nL/DOgVePO0/SyGAPIuMWOhnRx/5gh7pvZIO635d87adk4J6iYOCcBXJJGwhVpx7Xxg60MQ0KVN0c3LzPAkwnnq8ADexvW3PbdunkYLebZjiTZSuyNMlA9naYIIwzz4HyiVN8BcjOklF5j+xFwvDUEj4Apmr85cAgXnstroLUMGYMFbfFj7bH/msqGKcMNW++KbqkHqzbivwSnNEeViXai8fo7LnLEeHFQQ9Ijwar3aG6xIGA8a/sFU1IX8iwFucn5UVG9km3jMhv6xwScojp6qrtIsY63APXKJSLYL36M=
10 changes: 10 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,10 @@
# Change Log
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.1.0]
### Added

- Initial implementation accessible via `.run()` interface
7 changes: 6 additions & 1 deletion README.md
Expand Up @@ -325,4 +325,9 @@ integration but oh god where do we get such amount of time
## Future plans

- onTimeout state handlers
- Better documentation
- Better documentation
- Possibly dropping down OOP purity level (too many `this` calls for
JavaScript)
- Possibly converting `states: [{id: '<id>'}]` schema to
`states: { <id>: {} }`
- Possibly adding stages concept
25 changes: 25 additions & 0 deletions docs/internals.md
@@ -0,0 +1,25 @@
# Internals

## Architecture in two minutes

There are several entities in project:

- Scenario: a tree graph of states that transition on into another.
- Execution: object representing current scenario execution, contains
scenario itself, runtime, state-machine, dealas with launching state
machine and executing things not related to states (e.g. termination
handler)
- ExecutionRuntime: an object that is supplied as 'this' to state
transitions - basically this is just a sack of properties and helper
methods.
- State machine is a class that diverged from execution and is
basically a state scheduler. Execution had started to bloat up, so i've
decided to separate those concerns.
- Normalizer takes in scenario and tries to bring it in most
schema-compliant way, wrapping everything in promises, filling missed
things, etc.
- Validator validates that scenario is compliant with schema nd is
runnable.
- Utility modules supply boring helper functions, concurrent module is
a little bit, and i don't fully understand how some things have ended
there D:
2 changes: 1 addition & 1 deletion lib/execution/execution.js
Expand Up @@ -26,7 +26,7 @@ var ExecutionStatus = {
* @param {Scenario} scenario Scenario to execute.
* @param {StateMachine} machine State machine.
* @param {ExecutionRuntime} runtime Execution runtime.
* @param {Slf4jAlikeLogger} logger Logger instance.
* @param {InterpolationLoggerInterface} logger Logger instance.
*
* @property {AppEvents.CallAlerting|null} trigger CallAlerting event that triggered the scenario
* @property {AppEvents.Started} start Application start event
Expand Down
2 changes: 1 addition & 1 deletion lib/execution/runtime.js
Expand Up @@ -4,7 +4,7 @@
* @class
*
* @param {object} container Dependency injection container
* @param {Slf4jAlikeLogger} container.logger Logger instance
* @param {InterpolationLoggerInterface} container.logger Logger instance
* @param {object} [arguments] Scenario arguments (i.e. parsed custom data)
* @param {object} [data] Scenario runtime data (used by user functions)
*
Expand Down
2 changes: 1 addition & 1 deletion lib/execution/state-machine.js
Expand Up @@ -36,7 +36,7 @@ var MachineStatus = {
*
* @param {State[]} states
* @param {ExecutionRuntime} runtime
* @param {Slf4jAlikeLogger} logger
* @param {InterpolationLoggerInterface} logger
* @constructor
*/
function StateMachine(states, runtime, logger) {
Expand Down
18 changes: 11 additions & 7 deletions lib/index.js
Expand Up @@ -5,7 +5,7 @@ var Execution = require('./execution/execution').Execution,
TriggerType = schema.TriggerType,
validator = require('./schema/validator'),
normalizer = require('./schema/normalizer').Schema,
loggers = require('@ama-team/voxengine-sdk').loggers;
slf4j = require('@ama-team/voxengine-sdk').logger.slf4j;

//noinspection JSUnusedLocalSymbols
/**
Expand All @@ -16,13 +16,13 @@ var Execution = require('./execution/execution').Execution,
* @property {ExecutionSettings.customDataDeserializer} customDataDeserializer
* @property {object} container
* @property {object} data Pre-populated user data
* @property {LogLevel} logLevel
* @property {Level} logLevel
*/
function ExecutionSettings() {
this.customDataDeserializer = null;
this.container = {};
this.data = {};
this.logLevel = loggers.LogLevel.Info;
this.logLevel = slf4j.Level.Info;
}

/**
Expand Down Expand Up @@ -57,9 +57,12 @@ function compose(scenario, container, arguments, data, logLevel) {

scenario = normalizer.scenario(scenario);
validation = validator.validate(scenario);
logLevel = typeof logLevel === 'undefined' ? loggers.LogLevel.Info : logLevel;
logLevel = typeof logLevel === 'undefined' ? slf4j.LogLevel.Info : logLevel;
container = container || {};
logger = container.logger = container.logger ? container.logger : new loggers.slf4j(Logger, logLevel);
if (!container.logger) {
container.logger = new slf4j.Slf4j('ama-team.voxengine-scenario-framework', logLevel);
}
logger = container.logger;

violations = Object.keys(validation.violations)
.map(function (k) {
Expand All @@ -85,9 +88,10 @@ function compose(scenario, container, arguments, data, logLevel) {
* Takes incoming script and runs it whenever corresponding trigger is called.
*
* @param {Scenario|object} scenario Scenario (normalized or not) that has to be executed.
* @param {ExecutionSettings|object} settings User-defined settings.
* @param {ExecutionSettings|object} [settings] User-defined settings.
*/
function run(scenario, settings) {
settings = settings || new ExecutionSettings();
var container = settings.container || {},
args = deserializeArguments(VoxEngine.customData(), settings, container.logger),
execution = compose(scenario, container, args, settings.data || {}, settings.logLevel);
Expand Down Expand Up @@ -135,7 +139,7 @@ function execute(execution) {
*
* @param {string} customData
* @param {ExecutionSettings|object} settings
* @param {RichLoggerInterface} logger
* @param {InterpolationLoggerInterface} logger
*
* @return {object} Deserialized arguments
*/
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -46,7 +46,7 @@
},
"homepage": "https://github.com/ama-team/voxengine-scenario-framework#readme",
"dependencies": {
"@ama-team/voxengine-sdk": "github:ama-team/voxengine-sdk#dev"
"@ama-team/voxengine-sdk": "^0.1.0"
},
"devDependencies": {
"@ama-team/voxengine-definitions": "^0.1.0",
Expand Down
6 changes: 4 additions & 2 deletions test/helper/common.js
@@ -1,4 +1,6 @@
var loggers = require('@ama-team/voxengine-sdk').loggers,
var slf4j = require('@ama-team/voxengine-sdk').logger.slf4j,
Slf4j = slf4j.Slf4j,
LogLevel = slf4j.Level,
chai = require('chai'),
stderrLogger,
stdoutLogger,
Expand Down Expand Up @@ -68,7 +70,7 @@ function setup() {
}
};
runtimeLogs = [];
runtimeLogger = new loggers.slf4j(writer, loggers.LogLevel.All);
runtimeLogger = new Slf4j('ama-team.voxengine-scenario-framework.test.helper.common', LogLevel.All, writer);
});

afterEach(function () {
Expand Down
7 changes: 5 additions & 2 deletions test/spec/execution/state-machine.spec.js
Expand Up @@ -6,7 +6,9 @@ var stateMachineModule = require('../../../lib/execution/state-machine'),
TerminationCause = schema.TerminationCause,
concurrent = require('../../../lib/utility/concurrent'),
TimeoutException = concurrent.TimeoutException,
loggers = require('@ama-team/voxengine-sdk').loggers,
slf4j = require('@ama-team/voxengine-sdk').logger.slf4j,
Slf4j = slf4j.Slf4j,
LogLevel = slf4j.Level,
sinon = require('sinon'),
chai = require('chai'),
should = chai.should(),
Expand All @@ -33,7 +35,8 @@ describe('/execution', function () {
logs.push(message);
}
};
logger = new loggers.slf4j(writer, loggers.LogLevel.All);
var name = 'ama-team.voxengine-scenario-framework.test.spec.execution.state-machine';
logger = new Slf4j(name, LogLevel.All, writer);
factory = function (states) {
states.forEach(function (state) { state.timeouts = state.timeouts || {}; });
return new StateMachine(states, new ExecutionRuntime(), logger);
Expand Down
59 changes: 59 additions & 0 deletions test/spec/index.spec.js
@@ -0,0 +1,59 @@
var framework = require('../../lib/index'),
chai = require('chai'),
assert = chai.assert;

describe('/index.js', function () {

var scenario = {
states: [
{
id: 'entrypoint',
entrypoint: true,
transition: {trigger: 'terminated'}
},
{
id: 'terminated',
terminal: true
}
],
trigger: framework.TriggerType.Http
},
_engine = typeof VoxEngine === 'undefined' ? undefined : VoxEngine,
_logger = typeof Logger === 'undefined' ? undefined : Logger,
_events = typeof AppEvents === 'undefined' ? undefined : AppEvents;

beforeEach(function () {
VoxEngine = {
addEventListener: function (_, listener) {
listener();
},
customData: function () {
return '';
}
};
Logger = {
write: function () {}
};
AppEvents = {
Started: function () {}
}
});

afterEach(function () {
VoxEngine = _engine;
Logger = _logger;
AppEvents = _events;
});

describe('.run', function () {
it('should run scenario from index.js without hassle', function () {
return framework.run(scenario);
});
});

describe('.validate', function () {
it('should not throw any exception during regular call', function () {
assert(framework.validate(scenario));
});
});
});
11 changes: 11 additions & 0 deletions test/spec/schema/validator.spec.js
Expand Up @@ -80,6 +80,17 @@ describe('/schema', function () {
assert(result.violations.environment);
});

it('should block on missing scenario trigger', function () {
var scenario = scenarioFactory([stateFactory()]),
result;

scenario.trigger = null;
result = dumper(validator.validate(scenario));

assert(!result.valid);
assert(result.violations.trigger);
});

it('should block on missing scenario onTermination handler', function () {
var scenario = scenarioFactory([stateFactory()]),
result;
Expand Down

0 comments on commit f2f9ef0

Please sign in to comment.