fix: support integer arithmetic for divided_by, closes #465

This commit is contained in:
Harttle
2022-04-22 02:19:36 +08:00
parent ace5309c08
commit e69a51025e
5 changed files with 44 additions and 3 deletions
+18 -1
View File
@@ -26,6 +26,23 @@ Output
1.6666666666666667 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 [floor]: ./floor.html
+18 -1
View File
@@ -26,6 +26,23 @@ title: divided_by
1.6666666666666667 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 [floor]: ./floor.html
+1 -1
View File
@@ -4,7 +4,7 @@ export const abs = argumentsToValue(Math.abs)
export const atLeast = argumentsToValue(Math.max) export const atLeast = argumentsToValue(Math.max)
export const atMost = argumentsToValue(Math.min) export const atMost = argumentsToValue(Math.min)
export const ceil = argumentsToValue(Math.ceil) 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 floor = argumentsToValue(Math.floor)
export const minus = argumentsToValue((v: number, arg: number) => v - arg) export const minus = argumentsToValue((v: number, arg: number) => v - arg)
export const modulo = argumentsToValue((v: number, arg: number) => v % arg) export const modulo = argumentsToValue((v: number, arg: number) => v % arg)
+5
View File
@@ -199,6 +199,11 @@ describe('Issues', function () {
const html = engine.parseAndRenderSync('{{foo | size}}-{{bar.coo}}', { foo: 'foo', bar: Object.create({ coo: 'COO' }) }) const html = engine.parseAndRenderSync('{{foo | size}}-{{bar.coo}}', { foo: 'foo', bar: Object.create({ coo: 'COO' }) })
expect(html).to.equal('3-') 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 () => { it('#479 url_encode throws on undefined value', async () => {
const engine = new Liquid({ const engine = new Liquid({
strictVariables: false strictVariables: false
+2
View File
@@ -25,6 +25,8 @@ describe('filters/math', function () {
it('should return 2 for 4,2', () => test('{{4 | divided_by: 2}}', '2')) 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 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 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')) it('should convert string to number', () => test('{{"6" | divided_by: "3"}}', '2'))
}) })
describe('floor', function () { describe('floor', function () {