Skip to content

Commit

Permalink
feat: Conditions should be serialisable to JSON (#148)
Browse files Browse the repository at this point in the history
- rework Condition to use methods for both objects and strings
- change strain test to use Condition object
- use non-static Condition class again, softly replacing the string comparisons in the test
- add coverage for `null` condition
  • Loading branch information
dominique-pfister authored Sep 3, 2019
1 parent df6bc2d commit 5d7efc4
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 13 deletions.
56 changes: 51 additions & 5 deletions src/Condition.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

/* eslint-disable max-classes-per-file */
const url = require('url');
const YAML = require('yaml');
const utils = require('./utils.js');

// To avoid forward referencing the transformer function
let transform;
Expand Down Expand Up @@ -400,35 +402,79 @@ const propertyMap = {
},
};

/**
* StringCondition class
*/
class StringCondition {
constructor(s) {
this._s = s;
}

toVCL() {
return this._s;
}

toJSON() {
return this._s;
}

isEmpty() {
return this._s === '';
}
}

/**
* Condition class
*/
class Condition {
constructor(cfg) {
this._top = cfg ? transform(cfg) : null;
if (typeof cfg === 'string') {
this._top = new StringCondition(cfg);
} else {
this._top = cfg ? transform(cfg) : null;
}
}

toVCL() {
return this._top ? this._top.toVCL() : '';
}

toVCLPath(paramName = 'X-Base') {
return this._top ? this._top.toVCLPath(paramName) : '';
if (this._top && this._top.toVCLPath) {
return this._top.toVCLPath(paramName);
}
return '';
}

/* eslint-disable no-underscore-dangle */
toFunction() {
const self = this;
return (req) => {
if (self._top) {
if (self._top && self._top.evaluate) {
return self._top.evaluate(req);
}
return true;
};
}

toJSON() {
return this._top ? this._top.toJSON() : null;
toJSON(opts) {
const json = this._top ? this._top.toJSON() : null;
if (json && opts && opts.minimal) {
return utils.pruneEmptyValues(json);
}
return json;
}

toYAMLNode() {
const json = this.toJSON({ minimal: true });
return json ? YAML.createNode(json) : null;
}

isEmpty() {
if (this._top && this._top.isEmpty) {
return this._top.isEmpty();
}
return this._top === null;
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/Strain.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const Origin = require('./Origin.js');
const Static = require('./Static.js');
const Performance = require('./Performance.js');
const Redirect = require('./Redirect.js');
const Condition = require('../src/Condition.js');
const utils = require('./utils.js');
const log = require('./log.js');

Expand Down Expand Up @@ -47,7 +48,7 @@ class Strain {

// todo: schema for perf
this._perf = new Performance(cfg.perf);
this._condition = cfg.condition || '';
this._condition = new Condition(cfg.condition || '');

if (cfg.url) {
if (cfg.condition) {
Expand All @@ -59,7 +60,7 @@ class Strain {

// when `sticky` is not set
// assume the strain to be sticky when there is a condition
this._sticky = cfg.sticky === undefined ? this._condition !== '' : !!cfg.sticky;
this._sticky = cfg.sticky === undefined ? !this._condition.isEmpty() : !!cfg.sticky;

this._redirects = (Array.isArray(cfg.redirects) ? cfg.redirects : [])
.map((r) => new Redirect(r));
Expand Down Expand Up @@ -235,7 +236,7 @@ class Strain {
const json = {
name: this.name,
sticky: this.sticky,
condition: this.condition,
condition: this.condition.toJSON(opts),
perf: this.perf.toJSON(opts),
urls: this.urls,
};
Expand Down
6 changes: 6 additions & 0 deletions test/condition.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ describe('Condition tests', () => {
} else {
await assertOK(cond);
}
if (cfg.empty !== undefined) {
assert.equal(cfg.empty, cond.isEmpty());
}
if (cfg.json !== undefined) {
assert.equal(cfg.json, cond.toJSON());
}
const actual = cond.toJSON();
const expected = cfg.condition;
assert.deepEqual(actual, expected);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ vcl_path: ''

samples:
- match: true

empty: true
json: null
5 changes: 5 additions & 0 deletions test/specs/conditions/string.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Use a string based condition

condition: req.http.host == "client.project-helix.io"

vcl: 'req.http.host == "client.project-helix.io"'
3 changes: 2 additions & 1 deletion test/specs/configs/clone-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ strains:
- name: default
code: https://github.com/adobe/project-helix.io.git#master
static: https://github.com/adobe/project-helix.io.git#dev
condition: req.http.host == "client.project-helix.io"
condition:
url.hostname=: client.project-helix.io
sticky: false
content:
repo: helix-cli
Expand Down
10 changes: 6 additions & 4 deletions test/strains.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
const assert = require('assert');
const path = require('path');
const GitUrl = require('../src/GitUrl.js');
const Condition = require('../src/Condition.js');
const { HelixConfig, Strain } = require('../src/index.js');

const SPEC_ROOT = path.resolve(__dirname, 'specs/configs');
Expand Down Expand Up @@ -106,7 +107,8 @@ describe('Strains test', () => {
+ ' repo: helix-cli\n'
+ ' ref: master\n'
+ 'static: https://github.com/adobe/project-helix.io.git/htdocs#dev\n'
+ 'condition: req.http.host == "client.project-helix.io"\n'
+ 'condition:\n'
+ ' url.hostname=: client.project-helix.io\n'
+ 'directoryIndex: readme.html\n');

const fooCopy = cfg.strains.get('foo').clone();
Expand Down Expand Up @@ -232,19 +234,19 @@ describe('Strains test', () => {
assert.deepEqual(strain.content, giturl);
assert.deepEqual(strain.code, giturl);
assert.deepEqual(strain.package, '');
assert.deepEqual(strain.condition, '');
assert.equal(strain.condition.isEmpty(), true);

strain.name = 'dirty';
strain.content = 'https://github.com/adobe/project-helix.io.git#develop';
strain.code = 'https://github.com/adobe/project-helix.io.git#develop';
strain.package = 'dirty';
strain.condition = 'req.http.X-Dirty == "true"';
strain.condition = new Condition('req.http.X-Dirty == "true"');

assert.notDeepEqual(strain.name, 'test');
assert.notDeepEqual(strain.content, giturl);
assert.notDeepEqual(strain.code, giturl);
assert.notDeepEqual(strain.package, '');
assert.notDeepEqual(strain.condition, '');
assert.equal(strain.condition.isEmpty(), false);
});

it('proxy static can be read', () => {
Expand Down

0 comments on commit 5d7efc4

Please sign in to comment.