Skip to content

Commit

Permalink
LambdaExpression boolean function ((x) => x.prop == 1) Improvement.
Browse files Browse the repository at this point in the history
  • Loading branch information
fernandocode committed Jan 25, 2018
1 parent 558723f commit 9edadf9
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 22 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "./src/main.js",
"types": "./src/main.d.ts",
"scripts": {
"test": "mocha -r ts-node/register src/**/*.spec.ts",
"test": "tsc & mocha src/**/*.spec.js",
"showcase": "cd .\\showcase\\ npm run start-showcase"
},
"keywords": [
Expand Down
56 changes: 43 additions & 13 deletions src/expression-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,37 @@ export class ExpressionUtils {
return this.getPropertiesByExpressionString(strBeforeSemicon);
}

private getPropertiesByExpressionString(expression: string): string[] {
const propertiesReferences = expression.split(".");
if (propertiesReferences.length) {
propertiesReferences.shift();
} // remove alias
return propertiesReferences;
private hasAlias(value: string, alias: string | undefined): boolean {
if (!alias)
return true;
return value.indexOf(`${alias}.`) > -1;
}

private getColumnByLambdaExpression<T>(expression: LambdaExpression<T>): LambdaColumnMetadata {
private hasBetweenQuotes(value: string): boolean {
// let regexBetweenQuotes = /"[^"]*"/;
let regexBetweenQuotes = /^(["'])(.*)\1$/;
return regexBetweenQuotes.test(value);
}

private hasExpression(value: string, alias: string | undefined): boolean {
return !this.hasBetweenQuotes(value) && this.hasAlias(value, alias);
}

public getPropertiesByExpressionString(expression: string, alias: string | undefined = void 0): string[] {
if (this.hasExpression(expression, alias)) {
const propertiesReferences = expression.split(".");
if (propertiesReferences.length && this.hasExpression(expression, alias)) {
propertiesReferences.shift();
} // remove alias
return propertiesReferences;
}
return [expression];
}

public getColumnByLambdaExpression<T>(expression: LambdaExpression<T>): LambdaColumnMetadata {
const propertiesMetadada = this.getPropertiesByLambdaExpression(expression);
return {
alias: propertiesMetadada.alias,
columnLeft: this.getColumnByProperties(propertiesMetadada.propertiesLeft),
columnRight: this.getColumnByProperties(propertiesMetadada.propertiesRight),
operator: propertiesMetadada.operator,
Expand All @@ -63,25 +83,35 @@ export class ExpressionUtils {
private getPropertiesByLambdaExpression<T>(expression: LambdaExpression<T>): LambdaPropertiesMetadata {
const expressionMetadada = this.getExpressionByLambdaExpression(expression);
return {
alias: expressionMetadada.alias,
operator: expressionMetadada.operator,
propertiesLeft: this.getPropertiesByExpressionString(expressionMetadada.expressionLeft),
propertiesRight: this.getPropertiesByExpressionString(expressionMetadada.expressionRight),
propertiesLeft: this.getPropertiesByExpressionString(expressionMetadada.expressionLeft, expressionMetadada.alias),
propertiesRight: this.getPropertiesByExpressionString(expressionMetadada.expressionRight, expressionMetadada.alias),
};
}

private getExpressionByLambdaExpression<T>(expression: LambdaExpression<T>)
private getAlias(startExpression: string): string {
// https://stackoverflow.com/a/17779833/2290538
let regexBetweenParentheses = /\(([^)]+)\)/;
let resultRegex = regexBetweenParentheses.exec(startExpression);
return resultRegex && resultRegex.length > 1 ? resultRegex[1] : "";
}

public getExpressionByLambdaExpression<T>(expression: LambdaExpression<T>)
: LambdaExpressionMetadata {
let strAfterReturn = expression.toString().split("return")[1].trim();
if (!strAfterReturn) {
strAfterReturn = expression.toString().split("{")[1].trim();
let splitInitExpression = expression.toString().split("return");
if (!splitInitExpression) {
splitInitExpression = expression.toString().split("{");
}
let strAfterReturn = splitInitExpression[1].trim();
const strExpression = strAfterReturn.split(";")[0].split(" ");

if (strExpression.length !== 3) {
throw new Error(`Lambda expression '${expression.toString()}'
not supported! Use simple expression with '{expressionLeft} {operador} {expressionRight}'`);
}
return {
alias: this.getAlias(splitInitExpression[0]),
expressionLeft: strExpression[0],
expressionRight: strExpression[2],
operator: strExpression[1],
Expand Down
14 changes: 8 additions & 6 deletions src/metadatas.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
export interface LambdaExpressionMetadata {
export interface LambdaExpressionMetadata extends LambdaExpressionMetadataBase {
expressionLeft: string;
operator: string;
expressionRight: string;
}

export interface LambdaPropertiesMetadata {
export interface LambdaPropertiesMetadata extends LambdaExpressionMetadataBase {
propertiesLeft: string[];
operator: string;
propertiesRight: string[];
}

export interface LambdaColumnMetadata {
export interface LambdaColumnMetadata extends LambdaExpressionMetadataBase {
columnLeft: string;
operator: string;
columnRight: string;
}

export interface LambdaExpressionMetadataBase{
operator: string;
alias: string;
}
56 changes: 54 additions & 2 deletions src/test/test.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { LambdaExpressionMetadata } from './../metadatas';
import { ModelTest } from "./models/model-test";
import { expect } from "chai";
import { ExpressionUtils } from "../expression-utils";
import { Expression } from "../types";
import { LambdaExpression, Expression } from "../types";
import { LambdaColumnMetadata } from '../main';

const _expressionUtils: ExpressionUtils = new ExpressionUtils();
const _expressionUtilsCustomSeparador: ExpressionUtils = new ExpressionUtils("-");
Expand All @@ -11,6 +13,11 @@ export class ExpressionUsage {
public static expression<T>(expression: Expression<T>): string {
return _expressionUtils.getColumnByExpression(expression);
}

public static lambda<T>(expression: LambdaExpression<T>): LambdaColumnMetadata {
let result = _expressionUtils.getColumnByLambdaExpression(expression);
return result;
}
}

describe("Expression method", () => {
Expand Down Expand Up @@ -39,9 +46,54 @@ describe("Expression method", () => {
const result = _expressionUtils.getColumnByExpression<ModelTest>((x) => x.reference.id);
expect(result).to.equal("reference_id");
});
it("should return reference-id, with custom separator", () => {
it("should return reference-id with custom separator", () => {
const result = _expressionUtilsCustomSeparador.getColumnByExpression<ModelTest>((x) => x.reference.id);
expect(result).to.equal("reference-id");
});

});

describe("Lambda Expression method", () => {

it("should return id == 0", () => {
const result = ExpressionUsage.lambda<ModelTest>((x) => x.id == 0);
expect(result.columnLeft).to.equal("id");
expect(result.operator).to.equal("==");
expect(result.columnRight).to.equal("0");
});

it("should return column with column", () => {
const result = ExpressionUsage.lambda<ModelTest>((x) => x.id >= x.reference.id);
expect(result.columnLeft).to.equal("id");
expect(result.operator).to.equal(">=");
expect(result.columnRight).to.equal("reference_id");
});

it("should value similar column", () => {
const result1 = ExpressionUsage.lambda<ModelTest>((x) => x.name == "x.reference.id");
expect(result1.columnLeft).to.equal("name");
expect(result1.operator).to.equal("==");
expect(result1.columnRight).to.equal(`"x.reference.id"`);

const result2 = ExpressionUsage.lambda<ModelTest>((x) => x.name == 'x.reference.id');
expect(result2.columnLeft).to.equal("name");
expect(result2.operator).to.equal("==");
expect(result2.columnRight).to.equal(`'x.reference.id'`);
});


// it("should test", () => {
// const result = ExpressionUsage.lambda<ModelTest>((x) => x.id >= x.reference.id);
// expect(result.columnLeft).to.equal("x.id");
// expect(result.operator).to.equal(">=");
// expect(result.columnRight).to.equal("x.reference.id");

// console.log(_expressionUtils.getColumnByLambdaExpression<ModelTest>((x) => x.id >= x.reference.id));
// console.log(_expressionUtils.getColumnByLambdaExpression<ModelTest>((x) => x.id >= 0));

// const propertyRight = _expressionUtils.getPropertiesByExpressionString(result.expressionRight);
// console.log(propertyRight);
// console.log(_expressionUtils.getColumnByProperties(propertyRight));
// });

});

0 comments on commit 9edadf9

Please sign in to comment.