Repository: robertkrimen/otto
Pull request #516 (2023-12-30 00:03:34)

feat: add `trimStart` and `trimEnd` aliases
- The functionality for `trimStart` and `trimEnd` already existed within the `trimRight` and `trimLeft` functions
- This commit adds an alias and test for these functions



Patch:
diff --git a/builtin_string.go b/builtin_string.go
index 5b0f927..6ae7ed3 100644
--- a/builtin_string.go
+++ b/builtin_string.go
@@ -473,6 +473,14 @@ func builtinStringTrim(call FunctionCall) Value {
 		builtinStringTrimWhitespace))
 }
 
+func builtinStringTrimStart(call FunctionCall) Value {
+	return builtinStringTrimLeft(call)
+}
+
+func builtinStringTrimEnd(call FunctionCall) Value {
+	return builtinStringTrimRight(call)
+}
+
 // Mozilla extension, not ECMAScript 5.
 func builtinStringTrimLeft(call FunctionCall) Value {
 	checkObjectCoercible(call.runtime, call.This)
diff --git a/inline.go b/inline.go
index 6edaff6..51f7f44 100644
--- a/inline.go
+++ b/inline.go
@@ -2595,6 +2595,80 @@ func (rt *runtime) newContext() {
 					},
 				},
 			},
+			"trimStart": {
+				mode: 0o101,
+				value: Value{
+					kind: valueObject,
+					value: &object{
+						runtime:     rt,
+						class:       classFunctionName,
+						objectClass: classObject,
+						prototype:   rt.global.FunctionPrototype,
+						extensible:  true,
+						property: map[string]property{
+							propertyLength: {
+								mode: 0,
+								value: Value{
+									kind:  valueNumber,
+									value: 0,
+								},
+							},
+							propertyName: {
+								mode: 0,
+								value: Value{
+									kind:  valueString,
+									value: "trimStart",
+								},
+							},
+						},
+						propertyOrder: []string{
+							propertyLength,
+							propertyName,
+						},
+						value: nativeFunctionObject{
+							name: "trimStart",
+							call: builtinStringTrimStart,
+						},
+					},
+				},
+			},
+			"trimEnd": {
+				mode: 0o101,
+				value: Value{
+					kind: valueObject,
+					value: &object{
+						runtime:     rt,
+						class:       classFunctionName,
+						objectClass: classObject,
+						prototype:   rt.global.FunctionPrototype,
+						extensible:  true,
+						property: map[string]property{
+							propertyLength: {
+								mode: 0,
+								value: Value{
+									kind:  valueNumber,
+									value: 0,
+								},
+							},
+							propertyName: {
+								mode: 0,
+								value: Value{
+									kind:  valueString,
+									value: "trimEnd",
+								},
+							},
+						},
+						propertyOrder: []string{
+							propertyLength,
+							propertyName,
+						},
+						value: nativeFunctionObject{
+							name: "trimEnd",
+							call: builtinStringTrimEnd,
+						},
+					},
+				},
+			},
 			"toLocaleLowerCase": {
 				mode: 0o101,
 				value: Value{
@@ -2802,6 +2876,8 @@ func (rt *runtime) newContext() {
 			"trim",
 			"trimLeft",
 			"trimRight",
+			"trimStart",
+			"trimEnd",
 			"toLocaleLowerCase",
 			"toLocaleUpperCase",
 			"toLowerCase",
diff --git a/tools/gen-jscore/.gen-jscore.yaml b/tools/gen-jscore/.gen-jscore.yaml
index 6f523d8..524df5e 100644
--- a/tools/gen-jscore/.gen-jscore.yaml
+++ b/tools/gen-jscore/.gen-jscore.yaml
@@ -194,6 +194,10 @@ types:
           function: -1
         - name: trimRight
           function: -1
+        - name: trimStart
+          function: -1
+        - name: trimEnd
+          function: -1
         - name: toLocaleLowerCase
           function: -1
         - name: toLocaleUpperCase
@@ -226,27 +230,27 @@ types:
 
   - name: Number
     properties:
-    - name: length
-      value: 1
-    - name: prototype
-      value: rt.global.NumberPrototype
-    - name: isNaN
-      function: 1
-    - name: MAX_VALUE
-      value: math.MaxFloat64
-      kind: valueNumber
-    - name: MIN_VALUE
-      kind: valueNumber
-      value: math.SmallestNonzeroFloat64
-    - name: NaN
-      kind: valueNumber
-      value: math.NaN()
-    - name: NEGATIVE_INFINITY
-      kind: valueNumber
-      value: math.Inf(-1)
-    - name: POSITIVE_INFINITY
-      kind: valueNumber
-      value: math.Inf(+1)
+      - name: length
+        value: 1
+      - name: prototype
+        value: rt.global.NumberPrototype
+      - name: isNaN
+        function: 1
+      - name: MAX_VALUE
+        value: math.MaxFloat64
+        kind: valueNumber
+      - name: MIN_VALUE
+        kind: valueNumber
+        value: math.SmallestNonzeroFloat64
+      - name: NaN
+        kind: valueNumber
+        value: math.NaN()
+      - name: NEGATIVE_INFINITY
+        kind: valueNumber
+        value: math.Inf(-1)
+      - name: POSITIVE_INFINITY
+        kind: valueNumber
+        value: math.Inf(+1)
     prototype:
       prototype: Object
       value: prototypeValueNumber
@@ -270,90 +274,90 @@ types:
     class: Math
     objectPrototype: Object
     properties:
-        - name: abs
-          function: 1
-        - name: acos
-          function: 1
-        - name: acosh
-          function: 1
-        - name: asin
-          function: 1
-        - name: asinh
-          function: 1
-        - name: atan
-          function: 1
-        - name: atanh
-          function: 1
-        - name: atan2
-          function: 1
-        - name: cbrt
-          function: 1
-        - name: ceil
-          function: 1
-        - name: cos
-          function: 1
-        - name: cosh
-          function: 1
-        - name: exp
-          function: 1
-        - name: expm1
-          function: 1
-        - name: floor
-          function: 1
-        - name: log
-          function: 1
-        - name: log10
-          function: 1
-        - name: log1p
-          function: 1
-        - name: log2
-          function: 1
-        - name: max
-          function: 2
-        - name: min
-          function: 2
-        - name: pow
-          function: 2
-        - name: random
-          function: -1
-        - name: round
-          function: 1
-        - name: sin
-          function: 1
-        - name: sinh
-          function: 1
-        - name: sqrt
-          function: 1
-        - name: tan
-          function: 1
-        - name: tanh
-          function: 1
-        - name: trunc
-          function: 1
-        - name: E
-          kind: valueNumber
-          value: math.E
-        - name: LN10
-          kind: valueNumber
-          value: math.Ln10
-        - name: LN2
-          kind: valueNumber
-          value: math.Ln2
-        - name: LOG10E
-          kind: valueNumber
-          value: math.Log10E
-        - name: LOG2E
-          kind: valueNumber
-          value: math.Log2E
-        - name: PI
-          kind: valueNumber
-          value: math.Pi
-        - name: SQRT1_2
-          kind: valueNumber
-          value: sqrt1_2
-        - name: SQRT2
-          kind: valueNumber
-          value: math.Sqrt2
+      - name: abs
+        function: 1
+      - name: acos
+        function: 1
+      - name: acosh
+        function: 1
+      - name: asin
+        function: 1
+      - name: asinh
+        function: 1
+      - name: atan
+        function: 1
+      - name: atanh
+        function: 1
+      - name: atan2
+        function: 1
+      - name: cbrt
+        function: 1
+      - name: ceil
+        function: 1
+      - name: cos
+        function: 1
+      - name: cosh
+        function: 1
+      - name: exp
+        function: 1
+      - name: expm1
+        function: 1
+      - name: floor
+        function: 1
+      - name: log
+        function: 1
+      - name: log10
+        function: 1
+      - name: log1p
+        function: 1
+      - name: log2
+        function: 1
+      - name: max
+        function: 2
+      - name: min
+        function: 2
+      - name: pow
+        function: 2
+      - name: random
+        function: -1
+      - name: round
+        function: 1
+      - name: sin
+        function: 1
+      - name: sinh
+        function: 1
+      - name: sqrt
+        function: 1
+      - name: tan
+        function: 1
+      - name: tanh
+        function: 1
+      - name: trunc
+        function: 1
+      - name: E
+        kind: valueNumber
+        value: math.E
+      - name: LN10
+        kind: valueNumber
+        value: math.Ln10
+      - name: LN2
+        kind: valueNumber
+        value: math.Ln2
+      - name: LOG10E
+        kind: valueNumber
+        value: math.Log10E
+      - name: LOG2E
+        kind: valueNumber
+        value: math.Log2E
+      - name: PI
+        kind: valueNumber
+        value: math.Pi
+      - name: SQRT1_2
+        kind: valueNumber
+        value: sqrt1_2
+      - name: SQRT2
+        kind: valueNumber
+        value: math.Sqrt2
 
   - name: Date
     properties:


Test patch:
diff --git a/inline_test.go b/inline_test.go
index ed20ba1..849804a 100644
--- a/inline_test.go
+++ b/inline_test.go
@@ -105,10 +105,10 @@ func TestGetOwnPropertyNames(t *testing.T) {
 			"startsWith",
 			"toString",
 			"trim",
-			// "trimStart",
 			"trimLeft",
-			// "trimEnd",
 			"trimRight",
+			"trimStart",
+			"trimEnd",
 			"toLocaleLowerCase",
 			"toLocaleUpperCase",
 			"toLowerCase",
diff --git a/string_test.go b/string_test.go
index cd20799..3810e8b 100644
--- a/string_test.go
+++ b/string_test.go
@@ -479,3 +479,31 @@ func TestString_startsWith(t *testing.T) {
 		test(`'aa'.startsWith('a');`, true)
 	})
 }
+
+func TestString_trimStart(t *testing.T) {
+	tt(t, func() {
+		test, _ := test()
+
+		test(`"		abc\u000B".trimStart()`, "abc\u000B")
+		test(`"abc ".trimStart()`, "abc ")
+		test(`
+			var a = "\u180Eabc \u000B "
+			var b = a.trimStart()
+			a.length + b.length
+		`, 13)
+	})
+}
+
+func TestString_trimEnd(t *testing.T) {
+	tt(t, func() {
+		test, _ := test()
+
+		test(`"		abc\u000B".trimEnd()`, "		abc")
+		test(`" abc ".trimEnd()`, " abc")
+		test(`
+			var a = "\u180Eabc \u000B "
+			var b = a.trimEnd()
+			a.length + b.length
+		`, 11)
+	})
+}