Skip to content

Commit

Permalink
[FEATURE property-brace-expansion-improvement]
Browse files Browse the repository at this point in the history
  • Loading branch information
gordonkristan committed Jul 13, 2014
1 parent 938c514 commit 46afe8e
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 4 deletions.
6 changes: 6 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,9 @@ for a detailed explanation.

Added in [#5136](https://github.com/emberjs/ember.js/pull/5136)

* `property-brace-expansion-improvement`

Property brace expansion now allows multiple sets of braces to be used,
as well as not restricting their location in the string.

Added in [#4617](https://github.com/emberjs/ember.js/pull/4617)
3 changes: 2 additions & 1 deletion features.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"ember-routing-will-change-hooks": null,
"ember-routing-consistent-resources": true,
"event-dispatcher-can-disable-event-manager": null,
"ember-metal-is-present": null
"ember-metal-is-present": null,
"property-brace-expansion-improvement": null
},
"debugStatements": [
"Ember.warn",
Expand Down
49 changes: 46 additions & 3 deletions packages/ember-metal/lib/expand_properties.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Ember from "ember-metal/core";
import EmberError from 'ember-metal/error';
import { forEach } from 'ember-metal/enumerable_utils';

/**
@module ember-metal
*/

var BRACE_EXPANSION = /^((?:[^\.]*\.)*)\{(.*)\}$/;
var BRACE_EXPANSION = /^((?:[^\.]*\.)*)\{(.*)\}$/,
SPLIT_REGEX = /\{|\}/;

/**
Expands `pattern`, invoking `callback` for each expansion.
Expand All @@ -31,13 +33,21 @@ var BRACE_EXPANSION = /^((?:[^\.]*\.)*)\{(.*)\}$/;
expansion, and is passed the expansion.
*/
export default function expandProperties(pattern, callback) {
var match, prefix, list;

if (pattern.indexOf(' ') > -1) {
throw new EmberError('Brace expanded properties cannot contain spaces, ' +
'e.g. `user.{firstName, lastName}` should be `user.{firstName,lastName}`');
}

if (Ember.FEATURES.isEnabled('property-brace-expansion-improvement')) {
return newExpandProperties(pattern, callback);
} else {
return oldExpandProperties(pattern, callback);
}
}

function oldExpandProperties(pattern, callback) {
var match, prefix, list;

if (match = BRACE_EXPANSION.exec(pattern)) {
prefix = match[1];
list = match[2];
Expand All @@ -49,3 +59,36 @@ export default function expandProperties(pattern, callback) {
callback(pattern);
}
}

function newExpandProperties(pattern, callback) {
if ('string' === Ember.typeOf(pattern)) {
var parts = pattern.split(SPLIT_REGEX),
properties = [parts];

forEach(parts, function(part, index) {
if (part.indexOf(',') >= 0) {
properties = duplicateAndReplace(properties, part.split(','), index);
}
});

forEach(properties, function(property) {
callback(property.join(''));
});
} else {
callback(pattern);
}
}

function duplicateAndReplace(properties, currentParts, index) {
var all = [];

forEach(properties, function(property) {
forEach(currentParts, function(part) {
var current = property.slice(0);
current[index] = part;
all.push(current);
});
});

return all;
}
88 changes: 88 additions & 0 deletions packages/ember-metal/tests/expand_properties_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import Ember from "ember-metal/core";
import expandProperties from "ember-metal/expand_properties";

var foundProperties = [];

function addProperty(property) {
foundProperties.push(property);
}

QUnit.module('Property Brace Expansion Test', {
setup: function() {
foundProperties = [];
}
});

test('Properties without expansions are unaffected', function() {
expect(1);

expandProperties('a', addProperty);
expandProperties('a.b', addProperty);
expandProperties('a.b.@each', addProperty);

deepEqual(['a', 'a.b', 'a.b.@each'].sort(), foundProperties.sort());
});

test('A single expansion at the end expands properly', function() {
expect(1);

expandProperties('a.b.{c,d}', addProperty);

deepEqual(['a.b.c', 'a.b.d'].sort(), foundProperties.sort());
});

test('A property with only a brace expansion expands correctly', function() {
expect(1);

expandProperties('{a,b,c}', addProperty);

var expected = ['a', 'b', 'c'];
deepEqual(expected.sort(), foundProperties.sort());
});

if (!Ember.FEATURES.isEnabled('property-brace-expansion-improvement')) {
test('A brace expansion at the beginning doesn\'t expand' , function() {
expect(1);

expandProperties('{a,b,c}.d', addProperty);

deepEqual(['{a,b,c}.d'], foundProperties);
});
}

if (Ember.FEATURES.isEnabled('property-brace-expansion-improvement')) {
test('Expansions with single properties only expand once', function() {
expect(1);

expandProperties('a.b.{c}.d.{e}', addProperty);

deepEqual(['a.b.c.d.e'], foundProperties);
});

test('A single brace expansion expands correctly', function() {
expect(1);

expandProperties('a.{b,c,d}.e', addProperty);

var expected = ['a.b.e', 'a.c.e', 'a.d.e'];
deepEqual(expected.sort(), foundProperties.sort());
});

test('Multiple brace expansions work correctly', function() {
expect(1);

expandProperties('{a,b,c}.d.{e,f}.g', addProperty);

var expected = ['a.d.e.g', 'a.d.f.g', 'b.d.e.g', 'b.d.f.g', 'c.d.e.g', 'c.d.f.g'];
deepEqual(expected.sort(), foundProperties.sort());
});

test('A property with only brace expansions expands correctly', function() {
expect(1);

expandProperties('{a,b,c}.{d}.{e,f}', addProperty);

var expected = ['a.d.e', 'a.d.f', 'b.d.e', 'b.d.f', 'c.d.e', 'c.d.f'];
deepEqual(expected.sort(), foundProperties.sort());
});
}

0 comments on commit 46afe8e

Please sign in to comment.