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