Deal with large numerical values in statistics - fixes #87

Change-Id: Iaaf95fe1dd6c87c693446706d2845a80bb2d257f
diff --git a/Changes b/Changes
index a30f6bb..cf67a7e 100755
--- a/Changes
+++ b/Changes
@@ -1,3 +1,12 @@
+0.33 2019-03-18
+        - Fix problem with serialization and deserialization
+          of large numerical values (#87).
+
+        WARNING: This requires complete recaching, so run
+          $ perl script/kalamar chi clear default
+          $ perl script/kalamar chi clear user
+          in your MOJO_MODE environment after update.
+
 0.32 2019-03-12
         - Support attachements in metadata fields (#77).
         - Added ping request option to Piwik.
diff --git a/Makefile.PL b/Makefile.PL
index d03e5fc..f00a3ad 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -23,9 +23,13 @@
     'Mojolicious::Plugin::Util::RandomString' => 0.08,
     'Mojolicious::Plugin::CHI' => 0.20,
     'Mojolicious::Plugin::ClientIP' => 0.01,
-    'Cache::FastMmap' => 0,
+    'Cache::FastMmap' => 1.47,
+    'Data::Serializer' => 0.60,
     'Mojo::JWT' => 0.05,
 
+    # Required for Data::Serializer at the moment
+    'JSON' => 4.02,
+
     # Required for bundled plugins
     'Mojolicious::Plugin::Piwik' => 0.26,
 
diff --git a/dev/js/spec/statSpec.js b/dev/js/spec/statSpec.js
index 93001bd..38d6f64 100644
--- a/dev/js/spec/statSpec.js
+++ b/dev/js/spec/statSpec.js
@@ -73,6 +73,14 @@
   	"paragraphs":45454545
 	};
 
+	var preDefinedStat2={
+  	"documents":20216975,
+  	"tokens":  "5991667065",
+  	"sentences":403923016,
+  	"paragraphs":129385487
+	};
+
+  
   KorAP.API.getCorpStat = function(collQu, cb){
   	return cb(preDefinedStat);
   }; 
@@ -213,6 +221,33 @@
 			expect(descL.children[1].children[1].firstChild.nodeValue).toEqual(new Number(2323).toLocaleString());
 			expect(descL.children[1].children[0].attributes[0].value).toEqual('tokens');
     });
+
+    
+		it('should be parsed in a statistic view and displayed as HTML Description List (2)', function(){
+		  var stat = statClass.create(preDefinedStat2);
+          var descL = stat.element();
+			expect(descL.tagName).toEqual('DL');		
+			expect(descL.children[0].tagName).toEqual('DIV');
+			expect(descL.children[0].children[0].tagName).toEqual('DT');
+			expect(descL.children[0].children[0].attributes[0].name).toEqual('title');
+			expect(descL.children[0].children[1].tagName).toEqual('DD');
+			
+			expect(descL.children[0].children[0].firstChild.nodeValue).toEqual('documents');
+			expect(descL.children[0].children[1].firstChild.nodeValue).toEqual(new Number(20216975).toLocaleString());
+			expect(descL.children[0].children[0].attributes[0].value).toEqual('documents');
+
+			expect(descL.children[1].children[0].firstChild.nodeValue).toEqual('tokens');
+			expect(descL.children[1].children[1].firstChild.nodeValue).toEqual(new Number(5991667065).toLocaleString());
+			expect(descL.children[1].children[0].attributes[0].value).toEqual('tokens');
+
+			expect(descL.children[2].children[0].firstChild.nodeValue).toEqual('sentences');
+			expect(descL.children[2].children[1].firstChild.nodeValue).toEqual(new Number(403923016).toLocaleString());
+			expect(descL.children[2].children[0].attributes[0].value).toEqual('sentences');
+
+      expect(descL.children[3].children[0].firstChild.nodeValue).toEqual('paragraphs');
+			expect(descL.children[3].children[1].firstChild.nodeValue).toEqual(new Number(129385487).toLocaleString());
+			expect(descL.children[3].children[0].attributes[0].value).toEqual('paragraphs');
+    });
 		
 		
 		it('should display corpus statistic after creating a corpus statistic view', function(){
diff --git a/dev/js/src/vc/statistic.js b/dev/js/src/vc/statistic.js
index dd955b7..cd8d0ce 100644
--- a/dev/js/src/vc/statistic.js
+++ b/dev/js/src/vc/statistic.js
@@ -52,7 +52,7 @@
         statDT.addT(k);
         statDT.setAttribute('title', k);
         statDD = statSp.addE('dd');
-        statDD.addT(statistic[k].toLocaleString());
+        statDD.addT(new Number(statistic[k]).toLocaleString());
       }
 
       this._element = statDL;
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index 9fb75f7..1e8b0c7 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -8,7 +8,7 @@
 use List::Util 'none';
 
 # Minor version - may be patched from package.json
-our $VERSION = '0.31';
+our $VERSION = '0.33';
 
 # Supported version of Backend API
 our $API_VERSION = '1.0';
@@ -146,15 +146,28 @@
     $self->plugin($_);
   };
 
+  my $serializer = 'JSON';
+
+  if (my $chi = $self->config('CHI')) {
+    if ($chi->{default}) {
+      $chi->{default}->{serializer} = $serializer;
+    };
+    if ($chi->{user}) {
+      $chi->{user}->{serializer} = $serializer;
+    };
+  };
+
   # Global caching mechanism
   $self->plugin('CHI' => {
     default => {
       driver => 'Memory',
-      global => 1
+      global => 1,
+      serializer => $serializer
     },
     user => {
       driver => 'Memory',
-      global => 1
+      global => 1,
+      serializer => $serializer
     }
   });
 
diff --git a/package.json b/package.json
index 1c29790..9698fb6 100755
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "Kalamar",
   "description": "Mojolicious-based Frontend for KorAP",
   "license": "BSD-2-Clause",
-  "version": "0.32.2",
+  "version": "0.33.1",
   "pluginVersion": "0.1",
   "repository" : {
     "type": "git",
diff --git a/t/corpus_info.t b/t/corpus_info.t
index 551d052..e174bf0 100644
--- a/t/corpus_info.t
+++ b/t/corpus_info.t
@@ -27,10 +27,11 @@
 # Query passed
 $t->get_ok('/corpus')
   ->status_is(200)
-  ->json_is('/documents', 11)
-  ->json_is('/tokens', 665842)
-  ->json_is('/sentences', 25074)
-  ->json_is('/paragraphs', 772)
+  ->content_like(qr!"tokens":5991667065!)
+  ->json_is('/documents', 20216975)
+  ->json_is('/tokens', 5991667065)
+  ->json_is('/sentences', 403923016)
+  ->json_is('/paragraphs', 129385487)
   ->header_isnt('X-Kalamar-Cache', 'true')
   ;
 
@@ -51,10 +52,11 @@
 # Query passed
 $t->get_ok('/corpus')
   ->status_is(200)
-  ->json_is('/documents', 11)
-  ->json_is('/tokens', 665842)
-  ->json_is('/sentences', 25074)
-  ->json_is('/paragraphs', 772)
+  ->content_like(qr!"tokens":5991667065!)
+  ->json_is('/documents', 20216975)
+  ->json_is('/tokens', 5991667065)
+  ->json_is('/sentences', 403923016)
+  ->json_is('/paragraphs', 129385487)
   ->header_is('X-Kalamar-Cache', 'true')
   ;
 
diff --git a/t/corpus_info_cache.t b/t/corpus_info_cache.t
new file mode 100644
index 0000000..916a2d7
--- /dev/null
+++ b/t/corpus_info_cache.t
@@ -0,0 +1,68 @@
+use Mojo::Base -strict;
+use Test::Mojo;
+use Test::More;
+use Mojo::File qw/path/;
+
+
+#####################
+# Start Fake server #
+#####################
+my $mount_point = '/api/';
+$ENV{KALAMAR_API} = $mount_point;
+
+# New test with new cache
+my $t = Test::Mojo->new('Kalamar' => {
+  Kalamar => {},
+  CHI => {
+    default => {
+      driver => 'Memory',
+      global => 1,
+    },
+    default => {
+      driver => 'Memory',
+      global => 1,
+    },
+  }
+});
+
+is($t->app->config('CHI')->{default}->{serializer}, 'JSON');
+
+is($t->app->chi->driver_class, 'CHI::Driver::Memory');
+
+# Mount fake backend
+# Get the fixture path
+my $fixtures_path = path(Mojo::File->new(__FILE__)->dirname, 'server');
+my $fake_backend = $t->app->plugin(
+  Mount => {
+    $mount_point =>
+      $fixtures_path->child('mock.pl')
+  }
+);
+# Configure fake backend
+$fake_backend->pattern->defaults->{app}->log($t->app->log);
+
+# Query passed
+$t->get_ok('/corpus')
+  ->status_is(200)
+  ->content_like(qr!"tokens":5991667065!)
+  ->json_is('/documents', 20216975)
+  ->json_is('/tokens', 5991667065)
+  ->json_is('/sentences', 403923016)
+  ->json_is('/paragraphs', 129385487)
+  ->header_isnt('X-Kalamar-Cache', 'true')
+  ;
+
+# Query passed
+$t->get_ok('/corpus')
+  ->status_is(200)
+  ->content_like(qr!"tokens":5991667065!)
+  ->json_is('/documents', 20216975)
+  ->json_is('/tokens', 5991667065)
+  ->json_is('/sentences', 403923016)
+  ->json_is('/paragraphs', 129385487)
+  ->header_is('X-Kalamar-Cache', 'true')
+  ;
+
+
+done_testing;
+__END__
diff --git a/t/fixtures/response_corpusinfo.json b/t/fixtures/response_corpusinfo.json
index 1918da5..ad24f48 100644
--- a/t/fixtures/response_corpusinfo.json
+++ b/t/fixtures/response_corpusinfo.json
@@ -1,9 +1,9 @@
 {
   "status" : 200,
   "json" : {
-    "documents":11,
-    "tokens":665842,
-    "sentences":25074,
-    "paragraphs":772
+    "documents":20216975,
+    "tokens":5991667065,
+    "sentences":403923016,
+    "paragraphs":129385487
   }
 }