Skip to content

Commit

Permalink
Merge 852ca57 into 2aa5dc8
Browse files Browse the repository at this point in the history
  • Loading branch information
smelukov committed Aug 6, 2019
2 parents 2aa5dc8 + 852ca57 commit c72ab11
Show file tree
Hide file tree
Showing 7 changed files with 388 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.idea/
/.vscode/
/.cache/
/.nyc_output/
Expand Down
39 changes: 38 additions & 1 deletion src/buildin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ const {
addToSet,
getPropertyValue,
isPlainObject,
isRegExp
isRegExp,
isArrayLike
} = require('./utils');

module.exports = Object.freeze({
Expand Down Expand Up @@ -117,6 +118,42 @@ module.exports = Object.freeze({

return value !== undefined ? fn(value) : value;
},
slice: function(value, from, to, step) {
if (!isArrayLike(value)) {
return value;
}

if (step && step !== 1) {
const result = [];
const reverse = step < 0;

step *= Math.sign(step);

if (from < 0) {
from = value.length + from;
}

if (to < 0) {
to = value.length + to;
}

for (let i = from; i < to; i += step) {
result.push(value[i]);
}

if (reverse) {
result.reverse();
}

return result;
}

if (typeof value.slice === 'function') {
return value.slice(from, to);
}

return Array.prototype.slice.call(value, from, to);
},
recursive: function(value, getter) {
const result = new Set();

Expand Down
10 changes: 9 additions & 1 deletion src/methods.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const buildin = require('./buildin');
const {
addToSet,
isPlainObject
isPlainObject,
isArrayLike
} = require('./utils');

function noop() {}
Expand Down Expand Up @@ -128,6 +129,13 @@ module.exports = Object.freeze({

return current.slice().reverse();
},
slice: function(current, from, to) {
if (!isArrayLike(current)) {
return current;
}

return current.slice(from, to);
},
group: function(current, keyGetter, valueGetter) {
if (typeof keyGetter !== 'function') {
keyGetter = noop;
Expand Down
22 changes: 20 additions & 2 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,16 @@ const grammar = {
['. SYMBOL ( arguments )', code`method.$2(/*@2*/current, $4)`],
['.. SYMBOL', code`fn.recursive(/*@2*/current, "$2")`],
['..( block )', code`fn.recursive(current, current => { $2 })`],
['.[ block ]', code`fn.filter(current, current => { $2 })`]
['.[ block ]', code`fn.filter(current, current => { $2 })`],
['[ e : e ]', code`fn.slice(current, $2, $4, 1)`],
['[ e : e : e ]', code`fn.slice(current, $2, $4, $6)`],
['[ : e ]', code`fn.slice(current, 0, $3, 1)`],
['[ : e : e ]', code`fn.slice(current, 0, $3, $5)`],
['[ e : ]', code`fn.slice(current, $2, current.length, 1)`],
['[ e : : e ]', code`fn.slice(current, $2, current.length, $5)`],
['[ : ]', code`fn.slice(current, 0, current.length, 1)`],
['[ : : e ]', code`fn.slice(current, 0, current.length, $4)`],
['[ : : ]', code`fn.slice(current, 0, current.length, 1)`]
],

relativePath: [
Expand All @@ -266,7 +275,16 @@ const grammar = {
['query .. SYMBOL', code`fn.recursive(/*@3*/$1, "$3")`],
['query ..( block )', code`fn.recursive($1, current => { $3 })`],
['query .[ block ]', code`fn.filter($1, current => { $3 })`],
['query [ e ]', code`fn.map($1, $3)`]
['query [ e ]', code`fn.map($1, $3)`],
['query [ e : e ]', code`fn.slice($1, $3, $5, 1)`],
['query [ e : e : e ]', code`fn.slice($1, $3, $5, $7)`],
['query [ : e ]', code`fn.slice($1, 0, $4, 1)`],
['query [ : e : e ]', code`fn.slice($1, 0, $4, $6)`],
['query [ e : ]', code`fn.slice($1, $3, $1.length, 1)`],
['query [ e : : e ]', code`fn.slice($1, $2, $1.length, $6)`],
['query [ : ]', code`fn.slice($1, 0, $1.length, 1)`],
['query [ : : e ]', code`fn.slice($1, 0, $1.length, $5)`],
['query [ : : ]', code`fn.slice($1, 0, $1.length, 1)`]
],

arguments: [
Expand Down
9 changes: 8 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@ function isRegExp(value) {
return toString.call(value) === '[object RegExp]';
}

function isArrayLike(value) {
return value &&
hasOwnProperty.call(value, 0) &&
hasOwnProperty.call(value, 'length');
}

module.exports = {
addToSet,
getPropertyValue,
isPlainObject,
isRegExp
isRegExp,
isArrayLike
};
36 changes: 36 additions & 0 deletions test/methods-buildin.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,42 @@ describe('buildin methods', () => {
});
});

describe('slice()', () => {
it('arrays', () => {
assert.deepEqual(
query('filename.slice()')(data),
['1.css', '2.js', '3.svg', '4.js', '5.js', '6.css', '7.css']
);

assert.deepEqual(
query('filename.slice(1)')(data),
['2.js', '3.svg', '4.js', '5.js', '6.css', '7.css']
);

assert.deepEqual(
query('filename.slice(1, 3)')(data),
['2.js', '3.svg']
);
});

it('string', () => {
assert.deepEqual(
query('filename.pick().slice()')(data),
'1.css'
);

assert.deepEqual(
query('filename.pick().slice(1)')(data),
'.css'
);

assert.deepEqual(
query('filename.pick().slice(1, 2)')(data),
'.'
);
});
});

describe('keys()', () => {
it('basic', () => {
assert.deepEqual(
Expand Down

0 comments on commit c72ab11

Please sign in to comment.