mirror of
https://github.com/robertkrimen/otto
synced 2025-10-12 20:27:30 +08:00
Make parseInt behavior correspond to the 15.1.2.3 algorithm
This commit is contained in:
parent
a6d6f26c01
commit
16030f4b6f
24
builtin.go
24
builtin.go
|
@ -123,13 +123,31 @@ func builtinGlobal_parseInt(call FunctionCall) Value {
|
|||
return toValue(value)
|
||||
}
|
||||
|
||||
var parseFloat_matchBadSpecial = regexp.MustCompile(`[\+\-]?(?:[Ii]nf$|infinity)`)
|
||||
var parseFloat_matchValid = regexp.MustCompile(`[0-9eE\+\-\.]|Infinity`)
|
||||
|
||||
func builtinGlobal_parseFloat(call FunctionCall) Value {
|
||||
// Caveat emptor: This implementation does NOT match the specification
|
||||
string_ := strings.TrimSpace(toString(call.Argument(0)))
|
||||
value, err := strconv.ParseFloat(string_, 64)
|
||||
if err != nil {
|
||||
input := strings.TrimSpace(toString(call.Argument(0)))
|
||||
if parseFloat_matchBadSpecial.MatchString(input) {
|
||||
return NaNValue()
|
||||
}
|
||||
value, err := strconv.ParseFloat(input, 64)
|
||||
if err != nil {
|
||||
for end := len(input); end > 0; end -= 1 {
|
||||
input := input[0:end]
|
||||
if !parseFloat_matchValid.MatchString(input) {
|
||||
return NaNValue()
|
||||
}
|
||||
value, err = strconv.ParseFloat(input, 64)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return NaNValue()
|
||||
}
|
||||
}
|
||||
return toValue(value)
|
||||
}
|
||||
|
||||
|
|
|
@ -703,7 +703,7 @@ func newContext() *_runtime {
|
|||
"Infinity", positiveInfinityValue(),
|
||||
"eval", -1, builtinGlobal_eval,
|
||||
"parseInt", -2, builtinGlobal_parseInt,
|
||||
"parseFloat", builtinGlobal_parseFloat,
|
||||
"parseFloat", -1, builtinGlobal_parseFloat,
|
||||
"isNaN", builtinGlobal_isNaN,
|
||||
"isFinite", builtinGlobal_isFinite,
|
||||
"decodeURI", builtinGlobal_decodeURI_decodeURIComponent,
|
||||
|
|
|
@ -118,7 +118,9 @@ func Test_parseInt(t *testing.T) {
|
|||
test(`parseInt(" 11 ")`, "11")
|
||||
test(`parseInt(" 11\n")`, "11")
|
||||
test(`parseInt(" 11\n", 16)`, "17")
|
||||
|
||||
test(`parseInt("Xyzzy")`, "NaN")
|
||||
|
||||
test(`parseInt(" 0x11\n", 16)`, "17")
|
||||
test(`parseInt("0x0aXyzzy", 16)`, "10")
|
||||
test(`parseInt("0x1", 0)`, "1")
|
||||
|
@ -126,6 +128,7 @@ func Test_parseInt(t *testing.T) {
|
|||
// TODO
|
||||
test(`parseInt("0x10000000000000000000", 16)`, "75557863725914323419136")
|
||||
}
|
||||
|
||||
test(`parseInt.length === 2`, "true")
|
||||
test(`parseInt.prototype === undefined`, "true")
|
||||
}
|
||||
|
@ -141,14 +144,21 @@ func Test_parseFloat(t *testing.T) {
|
|||
test(`parseFloat(" 11 ")`, "11")
|
||||
test(`parseFloat(" 11\n")`, "11")
|
||||
test(`parseFloat(" 11\n", 16)`, "11")
|
||||
test(`parseFloat("Xyzzy")`, "NaN")
|
||||
test(`parseFloat("0x0a")`, "NaN")
|
||||
test(`parseFloat("11.1")`, "11.1")
|
||||
if false {
|
||||
test(`parseFloat(" 0x11\n", 16)`, "17")
|
||||
// TODO parseFloat should return 10 in this scenario
|
||||
test(`parseFloat("0x0aXyzzy")`, "10")
|
||||
}
|
||||
|
||||
test(`parseFloat("Xyzzy")`, "NaN")
|
||||
|
||||
test(`parseFloat(" 0x11\n", 16)`, "0")
|
||||
test(`parseFloat("0x0a")`, "0")
|
||||
test(`parseFloat("0x0aXyzzy")`, "0")
|
||||
test(`parseFloat("Infinity")`, "Infinity")
|
||||
test(`parseFloat("infinity")`, "NaN")
|
||||
test(`parseFloat("0x")`, "0")
|
||||
test(`parseFloat("11x")`, "11")
|
||||
test(`parseFloat("Infinity1")`, "Infinity")
|
||||
|
||||
test(`parseFloat.length === 1`, "true")
|
||||
test(`parseFloat.prototype === undefined`, "true")
|
||||
}
|
||||
|
||||
func Test_encodeURI(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user