The test is the ModuleTESTer singleton, is always passed and provides access to the mod(ule), the inst(ance - afer the .connect()) and tds (TestDataSpecs). More at a later time.
//
// ./__tsts/ADS1x15Ext_tst.js
//
var MOD = require("ADS1x15Ext");
var TDS = // ...TestDataSpec
{ vInfo: { v:1, d:20150915, a:"allObjects" }
, moduleName:"ADS1x15Ext"
, defaultI2CAddr: 0x48 // .addr after connect w/ new
, defaultAPGGain: 2048 // .gain after connect w/ new
, updatedAddr: 0xA5 // .addr after setAddr()
, updatedGain: 6144 // .gain after setGAin()
, invalidGain: 9999 // for setGAin()
, invalidGainXptnMsg: "Gain 9999 not found"
, gain4096: 4096 // .gain
, adcRaw0: 0 // raw 0
, adcRaw32767: 32767 // raw max
, adcRaw32768N: -32768 // raw min
, adcRaw1: 1 // raw 1
, adcRaw1N: -1 // raw -1
, ch0: 0 // channel 0 (1st)
, ch1: 1 // channel 1 (2nd)
, ch2: 2 // channel 2 (3rd)
, ch3: 3 // channel 3 (4th)
, readCnt: 2 // read count in bytes on read register 1..3
, vars:
{ i2c: null // used in test
, savedGain: -1 // used to save gain
, adcRaw: -1 // raw value read from ADC
}
, tsts: // tests
[ { id:"getModule():"
, f: function(test) { test.mod = require(test.tds.moduleName); }
, vals:
[ [ "mod !== undefined" ]
, [ "mod !== null" ]
, [ "typeof:mod.connect === function" ]
]
}
, { id:"connect():"
, f: function(test) { test.inst = test.mod.connect(test.tds.vars.i2c); }
, vals:
[ [ "inst !== undefined" ]
, [ "inst !== null" ]
, [ "inst.i2c === tds.vars.i2c" ]
, [ "inst.addr === tds.defaultI2CAddr" ]
, [ "inst.gain === tds.defaultAPGGain" ]
, [ "typeof:inst.setAddr === function" ]
, [ "typeof:inst.setGain === function" ]
]
}
, { id:"setAddr():"
, f: function(test) { test.inst.setAddr(test.tds.updatedAddr); }
, vals:
[ [ "inst.addr === tds.updatedAddr" ]
]
}
, { id:"setGain():"
, f: function(test) { test.inst.setGain(test.tds.updatedGain); }
, vals:
[ [ "inst.gain === tds.updatedGain" ]
]
}
, { id:"setGain() w invald gain:"
, f: function(test) {
test.tds.vars.savedGain = test.inst.gain;
test.inst.setGain(test.tds.invalidGain);
}
, vals: // exception happpens, gain stays untouched
[ [ "tstXptn.msg === tds.invalidGainXptnMsg" ]
, [ "tstXptn.type === Error" ]
, [ "inst.gain === tds.vars.savedGain" ]
]
}
, { id:"getADC() ch0 adcRaw0 0 via defaultI2CAddr:"
, f: function(test) {
test.inst.i2c.regs[0] = test.tds.adcRaw0;
test.inst.setAddr(test.tds.defaultI2CAddr);
test.inst.setGain(test.tds.gain4096);
test.inst.getADC(test.tds.ch0,function(raw){
test.tds.vars.adcRaw = raw;
});
return 2 * 8; // timeout to let timeouted callback happen
}
, vals: // ...not yet complete
[ [ "tds.vars.adcRaw === tds.adcRaw0" ]
, [ "inst.i2c.wAddr === tds.defaultI2CAddr" ]
, [ "inst.i2c.rAddr === tds.defaultI2CAddr" ]
, [ "inst.i2c.rCnt === tds.readCnt" ]
]
}
]
};
TDS.vars.i2c = // ...I2C mock / partial emulation just check used invocations
{ wAddr: -1 // write and...
, rAddr: -1 // ...read addr separate for complet getADC validation
, rCnt: -1 // read count
, reg: -1 // reg ptr
, regs: [-1,-1,-1,-1] // 4 16 bit regs
, writeTo: function(wAddr,reg,msb,lsb) {
this.wAddr = wAddr;
this.reg = reg;
if (typeof msb === "undefined") { return; } // ----> break
if (this.reg === 0) {
new Error("Conversion register 0 cannot be written to");
}
this.regs[this.reg] = (msb << 8) | lsb;
}
, readFrom: function(addr,cnt) {
this.rAddr = addr;
this.rCnt = cnt;
return new Uint8Array([this.regs[this.reg]>>8,this.regs[this.reg] & 0xFF]);
}
};
var MTEST = // Module TEST
{ vInfo: { v:1, d:20150915, a:"allObjects" }
, tds: null // test data spec
, dbg: false // debug
, mod: null // module
, inst: null // instance (afer new or new in connect)
, tstsOk: 0 // number of tests that succeeded
, tstsNOk: 0 // number of tests that failed
, validsOk: 0 // number of validations that succeeded
, validsNOk: 0 // number of validations that failed
, tme: undefined // ongoing timeout
, tstXptn: "" // exception last thrown by tst function/method
, tstIdx: -1, tstId: "nyd"
, valIdx: -1, valId: "nyd"
, test: function(tds) {
this.tds = tds;
this.mod = null;
this.inst = null;
this.tstsOk = 0;
this.tstsNOk = 0;
this.validsOk = 0;
this.validsNOk = 0;
this.tme = undefined;
this.tstXptn = "";
this.tstIdx = 0; tstId = "nyd";
this.valIdx = 0; valId = "nyd";
this.logHdr("-");
console.log("-");
this.logTest();
this._test();
}
, _test: function() {
var _this = this;
var tst = this.tds.tsts[this.tstIdx];
if (this.tme) {
this.tme = undefined;
} else {
this.tstId = tst.id; this.tstX = "";
try { this.tme = tst.f(this); } catch(tstXptn) { this.tstXptn = tstXptn; }
}
if (this.tme) {
setTimeout(function(){ _this._test(); },this.tme);
} else {
this.logTst();
if (this.dbg && (this.tstXptn)) { console.log(this.tstXptn); }
var tOk = true, vOK;
tst.vals.forEach(function(val,vdx){
this.valIdx = vdx;
if (val.length === 1) {
this.log(vOk = this.interpret(this.valId = val[0]));
} else {
this.valId = val[0];
this.log(vOk = val[1](this));
}
if (vOk) { this.validsOk++; } else { this.validsNOk++; }
tOk &= vOk;
},this);
if (tOk) { this.tstsOk++; } else { this.tstsNOk++; }
this.tstIdx++;
if (this.tstIdx < this.tds.tsts.length) {
setTimeout(function(){ _this._test(); },1);
} else {
this.logHdr("~");
this.logRslts("~");
}
}
}
, interpret: function(s) {
var sEs = s.split(" ");
return this[sEs[1]](this.resolve(sEs[0]),this.resolve(sEs[2]));
}
, resolve: function(s) { var r = null;
if (this.dbg) { console.log("resolve(): " + s); }
try { r = this[s]; if (typeof r === "undefined") {
if (s.indexOf("typeof:") === 0) {
r = typeof this.resolve(s.substr(7));
} else {
var ps = s.split("."), pc = ps.length, x = -1; r = this;
while (++x < pc) { r = r[ps[x]]; }
}
}
} catch(xptn) { throw new Error(
[ "Error:", this.tds.moduleName, this.tstId, this.valId
, "Unable to resolve:", s, "(", xptn, ")"
].join(" ") );
}
if (this.dbg) { console.log("resolve()d: " + r); }
return r;
}
, logHdr: function(pf) {
var tdsVInfo = this.tds.vInfo;
console.log("-"); console.log(
[ pf + " Module TEST:", this.tds.moduleName
, "vrsn:" + tdsVInfo.v, "date:" + tdsVInfo.d, "auth:" + tdsVInfo.a
].join(" "));
}
, logTest: function() {
console.log( "- " + this.tds.moduleName);
}
, logTst: function() {
console.log( "- " + this.tstId);
}
, log: function(ok) {
console.log(
[ ((ok) ? "- ok " : "- FAILED ")
, this.valId
].join(" "));
}
, logRslts: function(pf) {
console.log(pf + ((this.tstsNOk === 0) ? " ok " : " FAILED "));
this.logTV(pf,"tests",this.tstsOk,this.tstsNOk);
this.logTV(pf,"validations",this.validsOk,this.validsNOk);
console.log(pf);
}
, logTV: function(pf,tv,ok,nok) {
var v = ok + nok;
console.log(
[ pf, " ", Math.round(ok / v * 100), "% of "
, v, " ", tv, " passed", " (", ok, " : ", nok, ")"
].join(""));
}
};
MTEST["null" ] = null;
MTEST["undefined"] = undefined;
MTEST["function" ] = "function";
MTEST.number = "number";
MTEST.boolean = "boolean";
MTEST.Error = "Error";
MTEST["==="] = function(a,b) { var r = (a === b);
if (this.dbg) { console.log([a," === ",b].join(" ")); }
return r; };
MTEST["!=="] = function(a,b) { var r = (a !== b);
if (this.dbg) { console.log([a," !== ",b].join(" ")); }
return r; };
var debug = function(){ test(1); };
var test = function(dbg){ MTEST.dbg = dbg; MTEST.test(TDS); };
test();
Output in console:
-
- Module TEST: ADS1x15Ext vrsn:1 date:20150915 auth:allObjects
-
- ADS1x15Ext
- getModule():
- ok mod !== undefined
- ok mod !== null
- ok typeof:mod.connect === function
=undefined
- connect():
- ok inst !== undefined
- ok inst !== null
- ok inst.i2c === tds.vars.i2c
- ok inst.addr === tds.defaultI2CAddr
- ok inst.gain === tds.defaultAPGGain
- ok typeof:inst.setAddr === function
- ok typeof:inst.setGain === function
- setAddr():
- ok inst.addr === tds.updatedAddr
- setGain():
- ok inst.gain === tds.updatedGain
- setGain() w invald gain:
- ok tstXptn.msg === tds.invalidGainXptnMsg
- ok tstXptn.type === Error
- ok inst.gain === tds.vars.savedGain
- getADC() ch0 adcRaw0 0 via defaultI2CAddr:
- ok tds.vars.adcRaw === tds.adcRaw0
- ok inst.i2c.wAddr === tds.defaultI2CAddr
- ok inst.i2c.rAddr === tds.defaultI2CAddr
- ok inst.i2c.rCnt === tds.readCnt
-
~ Module TEST: ADS1x15Ext vrsn:1 date:20150915 auth:allObjects
~ ok
~ 100% of 6 tests passed (6 : 0)
~ 100% of 19 validations passed (19 : 0)
~
>
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
Soft-Tested with the attached file.
ADStxt15Ext.js is the module (modified name for temporary coexistence in my sandbox modules folder.
ADS1x15Ext_tst.js is a testing approach with TDS - Test Data Specs and the MTEST - Module TESTer.
A validation (in
vals:[]
) can be specified in two formats:or
The following two are exactly the same:
The
test
is the ModuleTESTer singleton, is always passed and provides access to themod
(ule), theinst
(ance - afer the.connect()
) andtds
(TestDataSpecs). More at a later time.Output in console:
2 Attachments