isNumeric.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #include "isNumeric.h"
  2. #include "../../Source/NumberToString.h"
  3. /*
  4. *
  5. * !!! ATTENTION !!!
  6. *
  7. * libjson currently has three number parsing methods, they are being merged
  8. * behind the scenes, but all three interfaces must be consistent, so every set
  9. * of numbers need to be tested in all three spots
  10. *
  11. * JSONValidator/isValidNumber *this file*
  12. * NumberToString/isNumeric
  13. * NumberToString/_atof
  14. */
  15. testNumberToString__isNumeric::testNumberToString__isNumeric(const std::string & name) : BaseTest(name){
  16. /*
  17. #ifndef JSON_STRICT
  18. ScopeCoverageHeap(isNumeric, 34);
  19. #else
  20. ScopeCoverageHeap(isNumeric, 35);
  21. #endif
  22. */
  23. }
  24. testNumberToString__isNumeric::~testNumberToString__isNumeric(){
  25. //AssertScopeCoverageHeap(isNumeric);
  26. }
  27. /**
  28. * Tests regular positive numbers in various forms
  29. */
  30. void testNumberToString__isNumeric::testPositive(void){
  31. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  32. assertTrue(NumberToString::isNumeric(JSON_TEXT("123")));
  33. assertTrue(NumberToString::isNumeric(JSON_TEXT("12.3")));
  34. assertTrue(NumberToString::isNumeric(JSON_TEXT("0.123")));
  35. assertTrue(NumberToString::isNumeric(JSON_TEXT("0")));
  36. assertTrue(NumberToString::isNumeric(JSON_TEXT("0.")));
  37. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.")));
  38. assertTrue(NumberToString::isNumeric(JSON_TEXT("1")));
  39. assertTrue(NumberToString::isNumeric(JSON_TEXT("0.0")));
  40. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.0")));
  41. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.01")));
  42. #endif
  43. }
  44. /**
  45. * Tests negative numbers with regular scientifc notation
  46. */
  47. void testNumberToString__isNumeric::testNegative(void){
  48. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  49. assertTrue(NumberToString::isNumeric(JSON_TEXT("-123")));
  50. assertTrue(NumberToString::isNumeric(JSON_TEXT("-12.3")));
  51. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.123")));
  52. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0")));
  53. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.")));
  54. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1")));
  55. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.")));
  56. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.0")));
  57. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.0")));
  58. #endif
  59. }
  60. /**
  61. * Tests positive numbers with scientific notiation that has a sign in it
  62. */
  63. void testNumberToString__isNumeric::testPositive_ScientificNotation(void){
  64. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  65. assertTrue(NumberToString::isNumeric(JSON_TEXT("0e123")));
  66. assertFalse(NumberToString::isNumeric(JSON_TEXT("0e12.3")));
  67. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.e123")));
  68. assertFalse(NumberToString::isNumeric(JSON_TEXT("1.e12.3")));
  69. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.0e123")));
  70. assertFalse(NumberToString::isNumeric(JSON_TEXT("1.0e12.3")));
  71. assertTrue(NumberToString::isNumeric(JSON_TEXT("0e2")));
  72. assertTrue(NumberToString::isNumeric(JSON_TEXT("1e2")));
  73. assertTrue(NumberToString::isNumeric(JSON_TEXT("0.e2")));
  74. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.e2")));
  75. assertTrue(NumberToString::isNumeric(JSON_TEXT("0.0e2")));
  76. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.0e2")));
  77. #endif
  78. }
  79. /**
  80. * Tests negative numbers with regular scientifc notation
  81. */
  82. void testNumberToString__isNumeric::testNegative_ScientificNotation(void){
  83. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  84. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0e123")));
  85. assertFalse(NumberToString::isNumeric(JSON_TEXT("-0e12.3")));
  86. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.e123")));
  87. assertFalse(NumberToString::isNumeric(JSON_TEXT("-1.e12.3")));
  88. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.0e123")));
  89. assertFalse(NumberToString::isNumeric(JSON_TEXT("-1.0e12.3")));
  90. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0e2")));
  91. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1e2")));
  92. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.e2")));
  93. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.e2")));
  94. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.0e2")));
  95. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.0e2")));
  96. #endif
  97. }
  98. /**
  99. * Tests positive numbers with scientific notiation that has a sign in it
  100. */
  101. void testNumberToString__isNumeric::testPositive_SignedScientificNotation(void){
  102. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  103. assertTrue(NumberToString::isNumeric(JSON_TEXT("0e-123")));
  104. assertTrue(NumberToString::isNumeric(JSON_TEXT("0e+123")));
  105. assertFalse(NumberToString::isNumeric(JSON_TEXT("0e-12.3"))); //period not supposed to be in there, exponent must be int
  106. assertFalse(NumberToString::isNumeric(JSON_TEXT("0e+12.3")));
  107. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.e-123")));
  108. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.e+123")));
  109. assertFalse(NumberToString::isNumeric(JSON_TEXT("1.e-12.3")));
  110. assertFalse(NumberToString::isNumeric(JSON_TEXT("1.e+12.3")));
  111. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.0e-123")));
  112. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.0e+123")));
  113. assertFalse(NumberToString::isNumeric(JSON_TEXT("1.0e-12.3")));
  114. assertFalse(NumberToString::isNumeric(JSON_TEXT("1.0e+12.3")));
  115. assertTrue(NumberToString::isNumeric(JSON_TEXT("0e2")));
  116. assertTrue(NumberToString::isNumeric(JSON_TEXT("1e2")));
  117. assertTrue(NumberToString::isNumeric(JSON_TEXT("0.e2")));
  118. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.e2")));
  119. assertTrue(NumberToString::isNumeric(JSON_TEXT("0.0e2")));
  120. assertTrue(NumberToString::isNumeric(JSON_TEXT("1.0e2")));
  121. #endif
  122. }
  123. /**
  124. * Tests negative numbers with scientific notiation that has a sign in it
  125. */
  126. void testNumberToString__isNumeric::testNegative_SignedScientificNotation(void){
  127. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  128. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0e-123")));
  129. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0e+123")));
  130. assertFalse(NumberToString::isNumeric(JSON_TEXT("-0.e-12.3")));
  131. assertFalse(NumberToString::isNumeric(JSON_TEXT("-0.e+12.3")));
  132. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.e-123")));
  133. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.e+123")));
  134. assertFalse(NumberToString::isNumeric(JSON_TEXT("-1.e-12.3")));
  135. assertFalse(NumberToString::isNumeric(JSON_TEXT("-1.e+12.3")));
  136. assertFalse(NumberToString::isNumeric(JSON_TEXT("-0.0e-12.3")));
  137. assertFalse(NumberToString::isNumeric(JSON_TEXT("-0.0e+12.3")));
  138. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.0e-123")));
  139. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.0e+123")));
  140. assertFalse(NumberToString::isNumeric(JSON_TEXT("-1.0e-12.3")));
  141. assertFalse(NumberToString::isNumeric(JSON_TEXT("-1.0e+12.3")));
  142. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0e-2")));
  143. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1e-2")));
  144. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.e-2")));
  145. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.e-2")));
  146. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.0e-2")));
  147. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.0e-2")));
  148. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0e+2")));
  149. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1e+2")));
  150. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.e+2")));
  151. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.e+2")));
  152. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0.0e+2")));
  153. assertTrue(NumberToString::isNumeric(JSON_TEXT("-1.0e+2")));
  154. #endif
  155. }
  156. /**
  157. * Tests that in strict mode, libjson isn't relaxed about what is and isn't
  158. * a valid number. libjson by default accepts a few extra common notations.
  159. */
  160. void testNumberToString__isNumeric::testStrict(void){
  161. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  162. #ifdef JSON_STRICT
  163. assertFalse(NumberToString::isNumeric(JSON_TEXT("00")));
  164. assertFalse(NumberToString::isNumeric(JSON_TEXT("00.01")));
  165. assertFalse(NumberToString::isNumeric(JSON_TEXT(".01")));
  166. assertFalse(NumberToString::isNumeric(JSON_TEXT("-.01")));
  167. assertFalse(NumberToString::isNumeric(JSON_TEXT("+123")));
  168. assertFalse(NumberToString::isNumeric(JSON_TEXT("+12.3")));
  169. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.123")));
  170. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0")));
  171. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.")));
  172. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e123")));
  173. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e-123")));
  174. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e+123")));
  175. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e123")));
  176. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e-123")));
  177. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e+123")));
  178. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e123")));
  179. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e-123")));
  180. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e+123")));
  181. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e123")));
  182. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e12.3")));
  183. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e-12.3")));
  184. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e+12.3")));
  185. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e12.3")));
  186. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e-12.3")));
  187. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e+12.3")));
  188. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e12.3")));
  189. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e-12.3")));
  190. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e+12.3")));
  191. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e12.3")));
  192. assertFalse(NumberToString::isNumeric(JSON_TEXT("0x12FF")));
  193. assertFalse(NumberToString::isNumeric(JSON_TEXT("0128"))); //legal because in STRICT mode, this is not octal, leading zero is ignored
  194. assertFalse(NumberToString::isNumeric(JSON_TEXT("0123")));
  195. assertFalse(NumberToString::isNumeric(JSON_TEXT("-0128")));
  196. assertFalse(NumberToString::isNumeric(JSON_TEXT("-0123")));
  197. assertFalse(NumberToString::isNumeric(JSON_TEXT("0xABCD")));
  198. assertFalse(NumberToString::isNumeric(JSON_TEXT("0124")));
  199. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1")));
  200. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.")));
  201. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.0")));
  202. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0")));
  203. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e2")));
  204. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1e2")));
  205. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.e2")));
  206. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e2")));
  207. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.0e2")));
  208. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e2")));
  209. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e-2")));
  210. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1e-2")));
  211. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.e-2")));
  212. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e-2")));
  213. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.0e-2")));
  214. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e-2")));
  215. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0e+2")));
  216. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1e+2")));
  217. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.e+2")));
  218. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.e+2")));
  219. assertFalse(NumberToString::isNumeric(JSON_TEXT("+0.0e+2")));
  220. assertFalse(NumberToString::isNumeric(JSON_TEXT("+1.0e+2")));
  221. assertFalse(NumberToString::isNumeric(JSON_TEXT("1e-0123"))); //not valid because of negative and leading zero
  222. #endif
  223. #endif
  224. }
  225. /**
  226. * Tests that the extra common notations that libjson supports all
  227. * test out as valid
  228. */
  229. void testNumberToString__isNumeric::testNotStrict(void){
  230. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  231. #ifndef JSON_STRICT
  232. assertTrue(NumberToString::isNumeric(JSON_TEXT("00")));
  233. assertTrue(NumberToString::isNumeric(JSON_TEXT("00.01")));
  234. assertTrue(NumberToString::isNumeric(JSON_TEXT(".01")));
  235. assertTrue(NumberToString::isNumeric(JSON_TEXT("-.01")));
  236. assertTrue(NumberToString::isNumeric(JSON_TEXT("+123")));
  237. assertTrue(NumberToString::isNumeric(JSON_TEXT("+12.3")));
  238. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.123")));
  239. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0")));
  240. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.")));
  241. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0e123")));
  242. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0e-123")));
  243. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0e+123")));
  244. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.e123")));
  245. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.e-123")));
  246. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.e+123")));
  247. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.0e123")));
  248. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.0e-123")));
  249. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.0e+123")));
  250. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.e123")));
  251. assertTrue(NumberToString::isNumeric(JSON_TEXT("0x12FF")));
  252. #ifdef JSON_OCTAL
  253. assertFalse(NumberToString::isNumeric(JSON_TEXT("0128"))); //because of the 8
  254. assertTrue(NumberToString::isNumeric(JSON_TEXT("0123")));
  255. assertFalse(NumberToString::isNumeric(JSON_TEXT("-0128")));
  256. assertTrue(NumberToString::_atof(JSON_TEXT("-0123")));
  257. #else
  258. assertTrue(NumberToString::isNumeric(JSON_TEXT("0128"))); //because the leading 0 is ignored
  259. assertTrue(NumberToString::isNumeric(JSON_TEXT("0123")));
  260. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0128"))); //because the leading 0 is ignored
  261. assertTrue(NumberToString::isNumeric(JSON_TEXT("-0123")));
  262. #endif
  263. assertTrue(NumberToString::isNumeric(JSON_TEXT("0xABCD")));
  264. assertTrue(NumberToString::isNumeric(JSON_TEXT("0124")));
  265. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0")));
  266. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1")));
  267. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.")));
  268. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.")));
  269. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.0")));
  270. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.0")));
  271. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0e2")));
  272. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1e2")));
  273. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.e2")));
  274. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.e2")));
  275. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.0e2")));
  276. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.0e2")));
  277. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0e-2")));
  278. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1e-2")));
  279. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.e-2")));
  280. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.e-2")));
  281. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.0e-2")));
  282. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.0e-2")));
  283. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0e+2")));
  284. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1e+2")));
  285. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.e+2")));
  286. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.e+2")));
  287. assertTrue(NumberToString::isNumeric(JSON_TEXT("+0.0e+2")));
  288. assertTrue(NumberToString::isNumeric(JSON_TEXT("+1.0e+2")));
  289. assertTrue(NumberToString::isNumeric(JSON_TEXT("1e-0123")));
  290. #endif
  291. #endif
  292. }
  293. /**
  294. * This tests values that aren't numbers at all, to make sure they are
  295. * flagged as not valid
  296. */
  297. void testNumberToString__isNumeric::testNotNumbers(void){
  298. #if defined(JSON_SAFE) || defined(JSON_DEBUG)
  299. assertFalse(NumberToString::isNumeric(JSON_TEXT("")));
  300. assertFalse(NumberToString::isNumeric(JSON_TEXT("-.")));
  301. assertFalse(NumberToString::isNumeric(JSON_TEXT("-e12")));
  302. assertFalse(NumberToString::isNumeric(JSON_TEXT("0xABCDv")));
  303. assertFalse(NumberToString::isNumeric(JSON_TEXT("00124")));
  304. assertFalse(NumberToString::isNumeric(JSON_TEXT("09124")));
  305. assertFalse(NumberToString::isNumeric(JSON_TEXT("0no")));
  306. assertFalse(NumberToString::isNumeric(JSON_TEXT("no")));
  307. assertFalse(NumberToString::isNumeric(JSON_TEXT("n1234")));
  308. assertFalse(NumberToString::isNumeric(JSON_TEXT("12no")));
  309. assertFalse(NumberToString::isNumeric(JSON_TEXT("0en5")));
  310. assertFalse(NumberToString::isNumeric(JSON_TEXT("0e")));
  311. assertFalse(NumberToString::isNumeric(JSON_TEXT("0E")));
  312. #endif
  313. }