summaryrefslogtreecommitdiff
path: root/t/02-number-handling.t
blob: 253fc369e3f42f2d981406644db3e2f6efbb277a (plain)
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Test::More 'no_plan';
  5. use Test::Trap qw(trap $trap);
  6. use Math::BigFloat;
  7. use LedgerSMB;
  8. use LedgerSMB::Form;
  9. my $lsmb_nan_message = "Content-Type: text/html; charset=utf-8\n\n<head></head><body><h2 class=\"error\">Error!</h2> <p><b>Invalid number detected during parsing</b></body>";
  10. my $form_nan_message = '<body><h2 class="error">Error!</h2> <p><b>Invalid number detected during parsing</b></body>';
  11. my @r;
  12. my $form = new Form;
  13. my %myconfig;
  14. ok(defined $form);
  15. isa_ok($form, 'Form');
  16. my $lsmb = new LedgerSMB;
  17. ok(defined $lsmb);
  18. isa_ok($lsmb, 'LedgerSMB');
  19. my $expected;
  20. foreach my $value ('0.01', '0.05', '0.015', '0.025', '1.1', '1.5', '1.9',
  21. '10.01', '4', '5', '5.1', '5.4', '5.5', '5.6', '6', '0',
  22. '0.000', '10.155', '55', '0.001', '14.5', '15.5', '4.5') {
  23. foreach my $places ('3', '2', '1', '0') {
  24. Math::BigFloat->round_mode('+inf');
  25. $expected = Math::BigFloat->new($value)->ffround(-$places);
  26. $expected->precision(undef);
  27. is($form->round_amount($value, $places), $expected,
  28. "form: $value to $places decimal places - $expected");
  29. is($lsmb->round_amount($value, $places), $expected,
  30. "lsmb: $value to $places decimal places - $expected");
  31. Math::BigFloat->round_mode('-inf');
  32. $expected = Math::BigFloat->new(-$value)->ffround(-$places);
  33. $expected->precision(undef);
  34. is($form->round_amount(-$value, $places), $expected,
  35. "form: -$value to $places decimal places - $expected");
  36. is($lsmb->round_amount(-$value, $places), $expected,
  37. "lsmb: -$value to $places decimal places - $expected");
  38. }
  39. foreach my $places ('-1', '-2') {
  40. Math::BigFloat->round_mode('+inf');
  41. $expected = Math::BigFloat->new($value)->ffround(-($places-1));
  42. is($form->round_amount($value, $places), $expected,
  43. "form: $value to $places decimal places - $expected");
  44. is($lsmb->round_amount($value, $places), $expected,
  45. "lsmb: $value to $places decimal places - $expected");
  46. Math::BigFloat->round_mode('-inf');
  47. $expected = Math::BigFloat->new(-$value)->ffround(-($places-1));
  48. is($form->round_amount(-$value, $places), $expected,
  49. "form: -$value to $places decimal places - $expected");
  50. is($lsmb->round_amount(-$value, $places), $expected,
  51. "lsmb: -$value to $places decimal places - $expected");
  52. }
  53. }
  54. # TODO Number formatting still needs work for l10n
  55. my @formats = (['1,000.00', ',', '.'], ["1'000.00", "'", '.'],
  56. ['1.000,00', '.', ','], ['1000,00', '', ','],
  57. ['1000.00', '', '.'], ['1 000.00', ' ', '.']);
  58. my %myfooconfig = (numberformat => '1000.00');
  59. foreach my $format (0 .. $#formats) {
  60. %myconfig = (numberformat => $formats[$format][0]);
  61. my $thou = $formats[$format][1];
  62. my $dec = $formats[$format][2];
  63. foreach my $rawValue ('10t000d00', '9t999d99', '333d33',
  64. '7t777t777d77', '-12d34', '0d00') {
  65. $expected = $rawValue;
  66. $expected =~ s/t/$thou/gx;
  67. $expected =~ s/d/$dec/gx;
  68. my $value = $rawValue;
  69. $value =~ s/t//gx;
  70. $value =~ s/d/\./gx;
  71. ##$value = Math::BigFloat->new($value);
  72. $value = $form->parse_amount(\%myfooconfig,$value);
  73. is($form->format_amount(\%myconfig, $value, 2, '0'), $expected,
  74. "form: $value formatted as $formats[$format][0] - $expected");
  75. is($lsmb->format_amount('user' => \%myconfig,
  76. 'amount' => $value, 'precision' => 2,
  77. 'neg_format' => '0'), $expected,
  78. "lsmb: $value formatted as $formats[$format][0] - $expected");
  79. }
  80. }
  81. foreach my $format (0 .. $#formats) {
  82. %myconfig = (numberformat => $formats[$format][0]);
  83. my $thou = $formats[$format][1];
  84. my $dec = $formats[$format][2];
  85. my $rawValue = '6d00';
  86. $expected = $rawValue;
  87. $expected =~ s/d/$dec/gx;
  88. my $value = $form->parse_amount(\%myfooconfig, '6');
  89. is($form->format_amount(\%myconfig, $value, 2, '0'), $expected,
  90. "form: $value formatted as $formats[$format][0] - $expected");
  91. is($lsmb->format_amount('user' => \%myconfig,
  92. 'amount' => $value, 'precision' => 2,
  93. 'neg_format' => '0'), $expected,
  94. "lsmb: $value formatted as $formats[$format][0] - $expected");
  95. }
  96. $expected = $form->parse_amount({'numberformat' => '1000.00'}, '0.00');
  97. is($form->format_amount({'numberformat' => '1000.00'} , $expected, 2, 'x'), 'x',
  98. "form: 0.00 with dash x");
  99. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  100. 'amount' => $expected, 'precision' => 2,
  101. 'neg_format' => 'x'), 'x',
  102. "lsmb: 0.00 with dash x");
  103. is($form->format_amount({'numberformat' => '1000.00'} , $expected, 2, ''), '',
  104. "form: 0.00 with dash ''");
  105. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  106. 'amount' => $expected, 'precision' => 2,
  107. 'neg_format' => ''), '',
  108. "lsmb: 0.00 with dash ''");
  109. is($form->format_amount({'numberformat' => '1000.00'} , $expected, 2), '',
  110. "form: 0.00 with undef dash");
  111. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  112. 'amount' => $expected, 'precision' => 2), '',
  113. "lsmb: 0.00 with undef dash");
  114. $ENV{GATEWAY_INTERFACE} = 'yes';
  115. $form->{pre} = 'Blah';
  116. $form->{header} = 'Blah';
  117. @r = trap{$form->format_amount({'apples' => '1000.00'}, 'foo', 2)};
  118. is($trap->exit, 0,
  119. 'form: No numberformat set, invalid amount (NaN check)');
  120. is($trap->stdout, $form_nan_message,
  121. 'form: No numberformat set, invalid amount message (NaN check)');
  122. @r = trap{$lsmb->format_amount('user' => {'apples' => '1000.00'},
  123. 'amount' => 'foo', 'precision' => 2)};
  124. is($trap->exit, 0,
  125. 'lsmb: No numberformat set, invalid amount (NaN check)');
  126. is($trap->stdout, $lsmb_nan_message,
  127. 'lsmb: No numberformat set, invalid amount message (NaN check)');
  128. cmp_ok($form->format_amount({'apples' => '1000.00'} , '1.00', 2), '==', 1,
  129. "form: No numberformat set, valid amount");
  130. cmp_ok($lsmb->format_amount('user' => {'apples' => '1000.00'},
  131. 'amount' => '1.00', 'precision' => 2), '==', 1,
  132. "lsmb: No numberformat set, valid amount");
  133. is($form->format_amount({'numberformat' => '1000.00'} , '-1.00', 2, '-'), '(1.00)',
  134. "form: -1.00 with dash '-'");
  135. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  136. 'amount' => '-1.00', 'precision' => 2, 'neg_format' => '-'), '(1.00)',
  137. "lsmb: -1.00 with dash '-'");
  138. is($form->format_amount({'numberformat' => '1000.00'} , '1.00', 2, '-'), '1.00',
  139. "form: 1.00 with dash '-'");
  140. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  141. 'amount' => '1.00', 'precision' => 2, 'neg_format' => '-'), '1.00',
  142. "lsmb: 1.00 with dash '-'");
  143. is($form->format_amount({'numberformat' => '1000.00'} , '-1.00', 2, 'DRCR'),
  144. '1.00 DR', "form: -1.00 with dash DRCR");
  145. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  146. 'amount' => '-1.00', 'precision' => 2, 'neg_format' => 'DRCR'),
  147. '1.00 DR', "lsmb: -1.00 with dash DRCR");
  148. is($form->format_amount({'numberformat' => '1000.00'} , '1.00', 2, 'DRCR'),
  149. '1.00 CR', "form: 1.00 with dash DRCR");
  150. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  151. 'amount' => '1.00', 'precision' => 2, 'neg_format' => 'DRCR'),
  152. '1.00 CR', "lsmb: 1.00 with dash DRCR");
  153. is($form->format_amount({'numberformat' => '1000.00'} , '-1.00', 2, 'x'), '-1.00',
  154. "form: -1.00 with dash 'x'");
  155. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  156. 'amount' => '-1.00', 'precision' => 2, 'neg_format' => 'x'), '-1.00',
  157. "lsmb: -1.00 with dash 'x'");
  158. is($form->format_amount({'numberformat' => '1000.00'} , '1.00', 2, 'x'), '1.00',
  159. "form: 1.00 with dash 'x'");
  160. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  161. 'amount' => '1.00', 'precision' => 2, 'neg_format' => 'x'), '1.00',
  162. "lsmb: 1.00 with dash 'x'");
  163. # Triggers the $amount .= "\.$dec" if ($dec ne ""); check to false
  164. is($form->format_amount({'numberformat' => '1000.00'} , '1.00'), '1',
  165. "form: 1.00 with no precision or dash (1000.00)");
  166. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  167. 'amount' => '1.00'), '1',
  168. "lsmb: 1.00 with no precision or dash (1000.00)");
  169. is($form->format_amount({'numberformat' => '1,000.00'} , '1.00'), '1',
  170. "form: 1.00 with no precision or dash (1,000.00)");
  171. is($lsmb->format_amount('user' => {'numberformat' => '1,000.00'},
  172. 'amount' => '1.00'), '1',
  173. "lsmb: 1.00 with no precision or dash (1,000.00)");
  174. is($form->format_amount({'numberformat' => '1 000.00'} , '1.00'), '1',
  175. "form: 1.00 with no precision or dash (1 000.00)");
  176. is($lsmb->format_amount('user' => {'numberformat' => '1 000.00'},
  177. 'amount' => '1.00'), '1',
  178. "lsmb: 1.00 with no precision or dash (1 000.00)");
  179. is($form->format_amount({'numberformat' => '1\'000.00'} , '1.00'), '1',
  180. "form: 1.00 with no precision or dash (1'000.00)");
  181. is($lsmb->format_amount('user' => {'numberformat' => '1\'000.00'},
  182. 'amount' => '1.00'), '1',
  183. "lsmb: 1.00 with no precision or dash (1'000.00)");
  184. is($form->format_amount({'numberformat' => '1.000,00'} , '1,00'), '1',
  185. "form: 1,00 with no precision or dash (1.000,00)");
  186. is($lsmb->format_amount('user' => {'numberformat' => '1.000,00'},
  187. 'amount' => '1,00'), '1',
  188. "lsmb: 1,00 with no precision or dash (1.000,00)");
  189. is($form->format_amount({'numberformat' => '1000,00'} , '1,00'), '1',
  190. "form: 1,00 with no precision or dash (1000,00)");
  191. is($lsmb->format_amount('user' => {'numberformat' => '1000,00'},
  192. 'amount' => '1,00'), '1',
  193. "lsmb: 1,00 with no precision or dash (1000,00)");
  194. is($form->format_amount({'numberformat' => '1000.00'} , '1.50'), '1.5',
  195. "form: 1.50 with no precision or dash");
  196. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  197. 'amount' => '1.50'), '1.5',
  198. "lsmb: 1.50 with no precision or dash");
  199. is($form->format_amount({'numberformat' => '1000.00'} , '0.0', undef, '0'), '0',
  200. "form: 0.0 with no precision, dash '0'");
  201. is($lsmb->format_amount('user' => {'numberformat' => '1000.00'},
  202. 'amount' => '0.0', 'neg_format' => '0'), '0',
  203. "lsmb: 0.0 with no precision, dash '0'");
  204. foreach my $format (0 .. $#formats) {
  205. %myconfig = (numberformat => $formats[$format][0]);
  206. my $thou = $formats[$format][1];
  207. my $dec = $formats[$format][2];
  208. foreach my $rawValue ('10t000d00', '9t999d99', '333d33',
  209. '7t777t777d77', '-12d34') {
  210. $expected = $rawValue;
  211. $expected =~ s/t/$thou/gx;
  212. $expected =~ s/d/$dec/gx;
  213. my $value = $rawValue;
  214. $value =~ s/t//gx;
  215. $value =~ s/d/\./gx;
  216. #my $ovalue = $value;
  217. $value = $form->parse_amount(\%myfooconfig,$value);
  218. #$value = $form->parse_amount(\%myconfig,$value);
  219. is($form->format_amount(\%myconfig,
  220. $form->format_amount(\%myconfig, $value, 2, 'x'),
  221. 2, 'x'), $expected,
  222. "form: Double formatting of $value as $formats[$format][0] - $expected");
  223. is($lsmb->format_amount('user' => \%myconfig,
  224. 'amount' =>
  225. $lsmb->format_amount('user' => \%myconfig,
  226. 'amount' => $value,
  227. 'precision' => 2,
  228. 'neg_format' => 'x'),
  229. 'precision' => 2, 'neg_format' => 'x'), $expected,
  230. "lsmb: Double formatting of $value as $formats[$format][0] - $expected");
  231. }
  232. }
  233. foreach my $format (0 .. $#formats) {
  234. %myconfig = ('numberformat' => $formats[$format][0]);
  235. my $thou = $formats[$format][1];
  236. my $dec = $formats[$format][2];
  237. foreach my $rawValue ('10t000d00', '9t999d99', '333d33',
  238. '7t777t777d77', '-12d34', '(76t543d21)') {
  239. $expected = $rawValue;
  240. $expected =~ s/t/$thou/gx;
  241. $expected =~ s/d/$dec/gx;
  242. my $value = $rawValue;
  243. $value =~ s/t//gx;
  244. $value =~ s/d/\./gx;
  245. if ($value =~ m/^\(/gx) {
  246. $value = Math::BigFloat->new('-'.substr($value, 1, -1));
  247. } else {
  248. $value = Math::BigFloat->new($value);
  249. }
  250. cmp_ok($form->parse_amount(\%myconfig, $expected), '==', $value,
  251. "form: $expected parsed as $formats[$format][0] - $value");
  252. cmp_ok($lsmb->parse_amount('user' => \%myconfig,
  253. 'amount' => $expected), '==', $value,
  254. "lsmb: $expected parsed as $formats[$format][0] - $value");
  255. }
  256. $expected = '12 CR';
  257. my $value = Math::BigFloat->new('12');
  258. cmp_ok($form->parse_amount(\%myconfig, $expected), '==', $value,
  259. "form: $expected parsed as $formats[$format][0] - $value");
  260. cmp_ok($lsmb->parse_amount('user' => \%myconfig, 'amount' => $expected),
  261. '==', $value,
  262. "lsmb: $expected parsed as $formats[$format][0] - $value");
  263. $expected = '21 DR';
  264. $value = Math::BigFloat->new('-21');
  265. cmp_ok($form->parse_amount(\%myconfig, $expected), '==', $value,
  266. "form: $expected parsed as $formats[$format][0] - $value");
  267. cmp_ok($lsmb->parse_amount('user' => \%myconfig, 'amount' => $expected),
  268. '==', $value,
  269. "lsmb: $expected parsed as $formats[$format][0] - $value");
  270. cmp_ok($form->parse_amount(\%myconfig, ''), '==', 0,
  271. "form: Empty string returns 0");
  272. @r = trap{$form->parse_amount(\%myconfig, 'foo')};
  273. is($trap->exit, 0,
  274. 'form: Invalid string gives NaN exit');
  275. is($trap->stdout, $form_nan_message,
  276. 'form: Invalid string gives NaN message');
  277. cmp_ok($lsmb->parse_amount('user' => \%myconfig, 'amount' => ''), '==', 0,
  278. "lsmb: Empty string returns 0");
  279. @r = trap{$lsmb->parse_amount('user' => \%myconfig, 'amount' => 'foo')};
  280. is($trap->exit, 0,
  281. 'lsmb: Invalid string gives NaN exit');
  282. is($trap->stdout, $lsmb_nan_message,
  283. 'lsmb: Invalid string gives NaN message');
  284. }
  285. foreach my $format (0 .. $#formats) {
  286. %myconfig = ('numberformat' => $formats[$format][0]);
  287. my $thou = $formats[$format][1];
  288. my $dec = $formats[$format][2];
  289. foreach my $rawValue ('10t000d00', '9t999d99', '333d33',
  290. '7t777t777d77', '-12d34', '(76t543d21)') {
  291. $expected = $rawValue;
  292. $expected =~ s/t/$thou/gx;
  293. $expected =~ s/d/$dec/gx;
  294. my $value = $rawValue;
  295. $value =~ s/t//gx;
  296. $value =~ s/d/\./gx;
  297. if ($value =~ m/^\(/gx) {
  298. $value = Math::BigFloat->new('-'.substr($value, 1, -1));
  299. } else {
  300. $value = Math::BigFloat->new($value);
  301. }
  302. cmp_ok($form->parse_amount(\%myconfig,
  303. $form->parse_amount(\%myconfig, $expected)),
  304. '==', $value,
  305. "form: $expected parsed as $formats[$format][0] - $value");
  306. cmp_ok($lsmb->parse_amount('user' => \%myconfig,
  307. 'amount' => $lsmb->parse_amount('user' => \%myconfig,
  308. 'amount' => $expected)),
  309. '==', $value,
  310. "lsmb: $expected parsed as $formats[$format][0] - $value");
  311. }
  312. $expected = '12 CR';
  313. my $value = Math::BigFloat->new('12');
  314. cmp_ok($form->parse_amount(\%myconfig,
  315. $form->parse_amount(\%myconfig, $expected)),
  316. '==', $value,
  317. "form: $expected parsed as $formats[$format][0] - $value");
  318. cmp_ok($lsmb->parse_amount('user' => \%myconfig,
  319. 'amount' => $lsmb->parse_amount('user' => \%myconfig,
  320. 'amount' => $expected)),
  321. '==', $value,
  322. "lsmb: $expected parsed as $formats[$format][0] - $value");
  323. $expected = '21 DR';
  324. $value = Math::BigFloat->new('-21');
  325. cmp_ok($form->parse_amount(\%myconfig,
  326. $form->parse_amount(\%myconfig, $expected)),
  327. '==', $value,
  328. "form: $expected parsed as $formats[$format][0] - $value");
  329. cmp_ok($lsmb->parse_amount('user' => \%myconfig,
  330. 'amount' => $lsmb->parse_amount('user' => \%myconfig,
  331. 'amount' => $expected)),
  332. '==', $value,
  333. "lsmb: $expected parsed as $formats[$format][0] - $value");
  334. cmp_ok($form->parse_amount(\%myconfig, ''), '==', 0,
  335. "form: Empty string returns 0");
  336. cmp_ok($form->parse_amount(\%myconfig), '==', 0,
  337. "form: undef string returns 0");
  338. @r = trap{$form->parse_amount(\%myconfig, 'foo')};
  339. is($trap->exit, 0,
  340. 'form: Invalid string gives NaN exit');
  341. is($trap->stdout, $form_nan_message,
  342. 'form: Invalid string gives NaN message');
  343. cmp_ok($lsmb->parse_amount('user' => \%myconfig), '==', 0,
  344. "lsmb: undef string returns 0");
  345. cmp_ok($lsmb->parse_amount('user' => \%myconfig, 'amount' => ''), '==', 0,
  346. "lsmb: Empty string returns 0");
  347. @r = trap{$lsmb->parse_amount('user' => \%myconfig, 'amount' => 'foo')};
  348. is($trap->exit, 0,
  349. 'lsmb: Invalid string gives NaN exit');
  350. is($trap->stdout, $lsmb_nan_message,
  351. 'lsmb: Invalid string gives NaN message');
  352. }