123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- let mocklib = global.mocklib;
- let byte = (str, off) => {
- let v = ord(str, off);
- return length(v) ? v[0] : v;
- };
- let hash = (s) => {
- let h = 7;
- for (let i = 0; i < length(s); i++)
- h = h * 31 + byte(s, i);
- return h;
- };
- let id = (config, t, n) => {
- while (true) {
- let id = sprintf('cfg%08x', hash(t + n));
- if (!exists(config, id))
- return id;
- n++;
- }
- };
- let fixup_config = (config) => {
- let rv = {};
- let n_section = 0;
- for (let stype in config) {
- switch (type(config[stype])) {
- case 'object':
- config[stype] = [ config[stype] ];
- /* fall through */
- case 'array':
- for (let idx, sobj in config[stype]) {
- let sid, anon;
- if (exists(sobj, '.name') && !exists(rv, sobj['.name'])) {
- sid = sobj['.name'];
- anon = false;
- }
- else {
- sid = id(rv, stype, idx);
- anon = true;
- }
- rv[sid] = {
- '.index': n_section++,
- ...sobj,
- '.name': sid,
- '.type': stype,
- '.anonymous': anon
- };
- }
- break;
- }
- }
- for (let n, sid in sort(keys(rv), (a, b) => rv[a]['.index'] - rv[b]['.index']))
- rv[sid]['.index'] = n;
- return rv;
- };
- return {
- cursor: () => ({
- _configs: {},
- load: function(file) {
- let basename = replace(file, /^.+\//, ''),
- path = sprintf("uci/%s.json", basename),
- mock = mocklib.read_json_file(path);
- if (!mock || mock != mock) {
- mocklib.I("No configuration fixture defined for uci package %s.", file);
- mocklib.I("Provide a mock configuration through the following JSON file:\n%s\n", path);
- return null;
- }
- this._configs[basename] = fixup_config(mock);
- },
- _get_section: function(config, section) {
- if (!exists(this._configs, config)) {
- this.load(config);
- if (!exists(this._configs, config))
- return null;
- }
- let cfg = this._configs[config],
- extended = match(section, "^@([A-Za-z0-9_-]+)\[(-?[0-9]+)\]$");
- if (extended) {
- let stype = extended[1],
- sindex = +extended[2];
- let sids = sort(
- filter(keys(cfg), sid => cfg[sid]['.type'] == stype),
- (a, b) => cfg[a]['.index'] - cfg[b]['.index']
- );
- if (sindex < 0)
- sindex = sids.length + sindex;
- return cfg[sids[sindex]];
- }
- return cfg[section];
- },
- get: function(config, section, option) {
- let sobj = this._get_section(config, section);
- if (option && index(option, ".") == 0)
- return null;
- else if (sobj && option)
- return sobj[option];
- else if (sobj)
- return sobj[".type"];
- },
- get_all: function(config, section) {
- return section ? this._get_section(config, section) : this._configs[config];
- },
- foreach: function(config, stype, cb) {
- let rv = false;
- if (exists(this._configs, config)) {
- let cfg = this._configs[config],
- sids = sort(keys(cfg), (a, b) => cfg[a]['.index'] - cfg[b]['.index']);
- for (let i, sid in sids) {
- if (stype == null || cfg[sid]['.type'] == stype) {
- if (cb({ ...(cfg[sid]) }) === false)
- break;
- rv = true;
- }
- }
- }
- return rv;
- }
- })
- };
|