1// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package json
6
7import (
8	"regexp"
9	"testing"
10)
11
12func TestNumberIsValid(t *testing.T) {
13	// From: https://stackoverflow.com/a/13340826
14	var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`)
15
16	validTests := []string{
17		"0",
18		"-0",
19		"1",
20		"-1",
21		"0.1",
22		"-0.1",
23		"1234",
24		"-1234",
25		"12.34",
26		"-12.34",
27		"12E0",
28		"12E1",
29		"12e34",
30		"12E-0",
31		"12e+1",
32		"12e-34",
33		"-12E0",
34		"-12E1",
35		"-12e34",
36		"-12E-0",
37		"-12e+1",
38		"-12e-34",
39		"1.2E0",
40		"1.2E1",
41		"1.2e34",
42		"1.2E-0",
43		"1.2e+1",
44		"1.2e-34",
45		"-1.2E0",
46		"-1.2E1",
47		"-1.2e34",
48		"-1.2E-0",
49		"-1.2e+1",
50		"-1.2e-34",
51		"0E0",
52		"0E1",
53		"0e34",
54		"0E-0",
55		"0e+1",
56		"0e-34",
57		"-0E0",
58		"-0E1",
59		"-0e34",
60		"-0E-0",
61		"-0e+1",
62		"-0e-34",
63	}
64
65	for _, test := range validTests {
66		if !isValidNumber(test) {
67			t.Errorf("%s should be valid", test)
68		}
69
70		var f float64
71		if err := Unmarshal([]byte(test), &f); err != nil {
72			t.Errorf("%s should be valid but Unmarshal failed: %v", test, err)
73		}
74
75		if !jsonNumberRegexp.MatchString(test) {
76			t.Errorf("%s should be valid but regexp does not match", test)
77		}
78	}
79
80	invalidTests := []string{
81		"",
82		"invalid",
83		"1.0.1",
84		"1..1",
85		"-1-2",
86		"012a42",
87		"01.2",
88		"012",
89		"12E12.12",
90		"1e2e3",
91		"1e+-2",
92		"1e--23",
93		"1e",
94		"e1",
95		"1e+",
96		"1ea",
97		"1a",
98		"1.a",
99		"1.",
100		"01",
101		"1.e1",
102	}
103
104	for _, test := range invalidTests {
105		var f float64
106		if err := Unmarshal([]byte(test), &f); err == nil {
107			t.Errorf("%s should be invalid but unmarshal wrote %v", test, f)
108		}
109
110		if jsonNumberRegexp.MatchString(test) {
111			t.Errorf("%s should be invalid but matches regexp", test)
112		}
113	}
114}
115
116func BenchmarkNumberIsValid(b *testing.B) {
117	s := "-61657.61667E+61673"
118	for i := 0; i < b.N; i++ {
119		isValidNumber(s)
120	}
121}
122
123func BenchmarkNumberIsValidRegexp(b *testing.B) {
124	var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`)
125	s := "-61657.61667E+61673"
126	for i := 0; i < b.N; i++ {
127		jsonNumberRegexp.MatchString(s)
128	}
129}
130