Skip to content

Commit

Permalink
fix: support integer arithmetic for divided_by, closes #465
Browse files Browse the repository at this point in the history
  • Loading branch information
harttle committed Apr 21, 2022
1 parent ace5309 commit e69a510
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 3 deletions.
19 changes: 18 additions & 1 deletion docs/source/filters/divided_by.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ Output
1.6666666666666667
```

{% note info Integer Arithmetic %}Since JavaScript doesn't differentiate integers and floats, LiquidJS is not capable of integer arithmetic and the return type is always `number`, the string representation of which depends on its value.{% endnote %}
In JavaScript, float and integer shares the same type `number` and we cannot tell the difference. For example:

```javascript
// always true
5.0 === 5
```

You'll need to pass another `integerArithmetic` argument to enforce integer divide:

Input
```liquid
{{ 5 | divided_by: 3, true }}
```

Output
```text
1
```

[floor]: ./floor.html
19 changes: 18 additions & 1 deletion docs/source/zh-cn/filters/divided_by.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ title: divided_by
1.6666666666666667
```

{% note info Integer Arithmetic %}Since JavaScript doesn't differentiate integers and floats, LiquidJS is not capable of integer arithmetic and the return type is always `number`, the string representation of which depends on its value.{% endnote %}
在 JavaScript 里数字没有浮点和整数的区分,它们的类型都是 `number`

```javascript
// always true
5.0 === 5
```

因此如果需要做整数运算,需要传入额外的 `integerArithmetic` 参数:

Input
```liquid
{{ 5 | divided_by: 3, true }}
```

Output
```text
1
```

[floor]: ./floor.html
2 changes: 1 addition & 1 deletion src/builtin/filters/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const abs = argumentsToValue(Math.abs)
export const atLeast = argumentsToValue(Math.max)
export const atMost = argumentsToValue(Math.min)
export const ceil = argumentsToValue(Math.ceil)
export const dividedBy = argumentsToValue((v: number, arg: number) => v / arg)
export const dividedBy = argumentsToValue((dividend: number, divisor: number, integerArithmetic = false) => integerArithmetic ? Math.floor(dividend / divisor) : dividend / divisor)
export const floor = argumentsToValue(Math.floor)
export const minus = argumentsToValue((v: number, arg: number) => v - arg)
export const modulo = argumentsToValue((v: number, arg: number) => v % arg)
Expand Down
5 changes: 5 additions & 0 deletions test/e2e/issues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ describe('Issues', function () {
const html = engine.parseAndRenderSync('{{foo | size}}-{{bar.coo}}', { foo: 'foo', bar: Object.create({ coo: 'COO' }) })
expect(html).to.equal('3-')
})
it('#465 Liquidjs divided_by not compatible with Ruby/Shopify Liquid', () => {
const engine = new Liquid({ ownPropertyOnly: true })
const html = engine.parseAndRenderSync('{{ 5 | divided_by: 3, true }}')
expect(html).to.equal('1')
})
it('#479 url_encode throws on undefined value', async () => {
const engine = new Liquid({
strictVariables: false
Expand Down
2 changes: 2 additions & 0 deletions test/integration/builtin/filters/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ describe('filters/math', function () {
it('should return 2 for 4,2', () => test('{{4 | divided_by: 2}}', '2'))
it('should return 4 for 16,4', () => test('{{16 | divided_by: 4}}', '4'))
it('should return 1 for 5,3', () => test('{{5 | divided_by: 3}}', (5 / 3).toString()))
it('should support integer arithmetic', () => test('{{5 | divided_by: 3, true}}', '1'))
it('should floor the result in integer arithmetic', () => test('{{ -5 | divided_by: 3, true}}', '-2'))
it('should convert string to number', () => test('{{"6" | divided_by: "3"}}', '2'))
})
describe('floor', function () {
Expand Down

0 comments on commit e69a510

Please sign in to comment.