From c0d98f1cdba26e9d9a841f94ea43abed00ef616f Mon Sep 17 00:00:00 2001
From: librelois <elois@ifee.fr>
Date: Mon, 23 Apr 2018 18:24:41 +0200
Subject: [PATCH] [enh] add IO file features

---
 lib/index.js         |  12 +++++---
 native/src/lib.rs    |  33 +++++++++++++++++++++
 tests/g1_genesis.bin | Bin 0 -> 1795 bytes
 tests/test.js        |  69 ++++++++++++++++++++++++++++++-------------
 4 files changed, 89 insertions(+), 25 deletions(-)
 create mode 100644 tests/g1_genesis.bin

diff --git a/lib/index.js b/lib/index.js
index d096f0c..7b577e2 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -5,17 +5,17 @@ const path = require('path');
 
 module.exports = {
 
-    /*newFileInstance: (filePath) => {
+    newFileInstance: (filePath, sigStock) => {
         const instance = Object.create(WotB)
         if (process.platform == 'win32') {
         let bufferedPath = new Buffer(filePath,'ascii');
-        instance.init(wotb.newFileInstanceWin32(bufferedPath, bufferedPath.length))
+            instance.init(addon.new_file_instance_win_32(bufferedPath, bufferedPath.length, sigStock))
         } else {
-        instance.init(wotb.new_file_instance(filePath));
+            instance.init(addon.new_file_instance(filePath, sigStock));
         }
         instance.setFilePath(filePath)
         return instance
-    },*/
+    },
 
     newMemoryInstance: (sigStock) => {
         const instance = Object.create(WotB)
@@ -44,6 +44,10 @@ const WotB = {
         this.filePath = filePath
     },
 
+    write: function() {
+        return addon.write_instance_in_file(this.instanceID, this.filePath);
+    },
+
     memCopy: function() {
         const copy = Object.create(WotB)
         copy.instanceID = addon.mem_copy(this.instanceID);
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 52005fb..c5caa3c 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -8,6 +8,7 @@ use duniter_wotb::data::rusty::RustyWebOfTrust;
 use duniter_wotb::data::{HasLinkResult, NewLinkResult, NodeId, RemLinkResult, WebOfTrust};
 use duniter_wotb::operations::distance::{DistanceCalculator, RustyDistanceCalculator, WotDistance,
                                          WotDistanceParameters};
+use duniter_wotb::operations::file::{BinaryFileFormater, FileFormater};
 use duniter_wotb::operations::path::{PathFinder, RustyPathFinder};
 use neon::js::{JsArray, JsBoolean, JsInteger, JsNumber, JsObject, JsString, Object};
 use neon::vm::{Call, JsResult};
@@ -16,6 +17,7 @@ use std::ops::{Deref, DerefMut};
 
 static mut WOT_INSTANCES: Option<HashMap<usize, Box<RustyWebOfTrust>>> = None;
 static DISTANCE_CALCULATOR: RustyDistanceCalculator = RustyDistanceCalculator {};
+static FILE_FORMATER: BinaryFileFormater = BinaryFileFormater {};
 static PATH_FINDER: RustyPathFinder = RustyPathFinder {};
 
 fn get_wots() -> &'static mut HashMap<usize, Box<RustyWebOfTrust>> {
@@ -77,6 +79,35 @@ fn threading_hint(call: Call) -> JsResult<JsNumber> {
     Ok(JsNumber::new(call.scope, num_cpus::get() as f64))
 }
 
+fn new_file_instance(call: Call) -> JsResult<JsInteger> {
+    let scope = call.scope;
+    let file_path = try!(try!(call.arguments.require(scope, 0)).check::<JsString>()).value();
+    let max_links = try!(try!(call.arguments.require(scope, 1)).check::<JsInteger>()).value();
+    let (wot, _blockstamp) = FILE_FORMATER
+        .from_file(&file_path, max_links as usize)
+        .unwrap();
+    let wots = get_wots();
+    let mut instance_id = 0;
+    while wots.contains_key(&instance_id) {
+        instance_id += 1;
+    }
+    wots.insert(instance_id, Box::new(wot));
+    Ok(JsInteger::new(scope, instance_id as i32))
+}
+
+fn write_instance_in_file(call: Call) -> JsResult<JsBoolean> {
+    let scope = call.scope;
+    let instance_id =
+        try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value() as usize;
+    let file_path = try!(try!(call.arguments.require(scope, 1)).check::<JsString>()).value();
+    let wot = get_wot(instance_id as usize);
+    let header: Vec<u8> = Vec::with_capacity(0);
+    match FILE_FORMATER.to_file(wot, &header, &file_path) {
+        Ok(_) => Ok(JsBoolean::new(scope, true)),
+        Err(e) => panic!("Fatal error : fail to write wot in file : {:?}", e),
+    }
+}
+
 fn new_memory_instance(call: Call) -> JsResult<JsInteger> {
     let scope = call.scope;
     let max_links = try!(try!(call.arguments.require(scope, 0)).check::<JsInteger>()).value();
@@ -388,6 +419,8 @@ fn remove_wot(call: Call) -> JsResult<JsBoolean> {
 register_module!(m, {
     m.export("hello", hello)?;
     m.export("threadingHint", threading_hint)?;
+    m.export("new_file_instance", new_file_instance)?;
+    m.export("write_instance_in_file", write_instance_in_file)?;
     m.export("new_memory_instance", new_memory_instance)?;
     m.export("mem_copy", mem_copy)?;
     m.export("get_max_links", get_max_links)?;
diff --git a/tests/g1_genesis.bin b/tests/g1_genesis.bin
new file mode 100644
index 0000000000000000000000000000000000000000..e7838df9c9efb58d10cbbb7f8a3ba1a2a4407db5
GIT binary patch
literal 1795
zcmZQzU~smy)HN_LFfcT7bTP3sb9Ht!HFI$_aI$bUbun`@H?edwcXo0$w=gv|b~Q7$
zFf}$db~G_@H83$YH+OY&b9Qz#HD+L7u>KDL4@4Ol7#SG&7#PGE7}yyYWEdFa85npO
z7+4t?bQu^d85p=27(^KuG#D6I7#I{87)%%#I2jmt7#OS=7?>Cs_(d5Q#27%pih)6g
zfk6qZSq35p*2B)gU;#FQlYv13tWz9pC?D7+OCd0a2W%BT*e&v4OC-RWd10n=f-M&X
zJJX7RfsY;R06qo=VFm^v1_o{h24w~Y5h1WDVFm^Pumczv82G`y5(gX41GW+30a37H
zKqfITXt07+bAw&N&%nSS2v*Jx7Uc(9$pQ8?Bgmg1@A82C1o5#9*wdn7V7oZLA!r5m
zuLW3w5$pq9uzo(Ur3_$mxfmGOz}Cov-7L<)z{?JHpCs5%R$!|{85lSPz=m1DwDN&9
zDT3W94z^PsY#s;Lqrwaf8r)#J#KGDazyU4+jv7#Gfi+ukFffRKgN>PiK^1HrD>(eD
z*uZWv0UOT5z`()4V8z40pba)k930}1Ams$Rlo9L&83qOpPOx?cusR8_923|PRtyZx
z0$|fPz`-a0PH8OQG{OM(kr>#4OkkayVAm;efE^(L7Lo#oo+JZ<0s{j-8v}zJ1A_{f
zqt3t}&A=eZ0XAG2><4jhG7w>4V1_tb7wiF1u$7kJ1g#7X2S`!^1vbckVCBMKtwLZo
zGBGeH3xbWc0LKBuuae;8s0a&W39zY5U=1AL^lHfojtnMn0$>9tWF-a$NpM2Z;RSof
z3g&N1urc!BAc6#<5LlZMJ6H!N*e*~)1Se!G5pWopfJ2)PtVt9cQmkO>#lRU=2AoCt
z!ASv<b`-(h=VAw&!3PO01_m_-26YAoes*vms(?9i3=Fai3{sHLR00RMDA+EDYs48C
zwAsMH4hnFv4k-o(1$MBBQeZwLeq<RKR3PPuC^!b0z+r9ycCZ*Yyd=R<F2evSJ1p72
zew7BhSREYRQfy$3KG?e);6UJH2m6r|9E>vHU=w3tU}FQvmoV5nR*=NZ3FgRwT_p>4
z708ufJ0#e^$&(qJN+1c}iXAKjO)Ow*%^4WDAt{U#93TpCy^wN{1?&+?1_nMh7)uu%
z<?IX$maO2st_^k|F9U-(JD4R74n|(EawP@^8Ay7w06SO=oJ54dRx7iD?Xm<b)MQ}L
zfVe{n<{6MvAW@*ez@P_-D+UHxcCa^P!SM_c1;r36SYDceK_6_W9y{1K`Y??O;HZ>j
z2kU|q$pQ=vreL*9tl*$$0;hXZ1_l;L3B>?TLXu!F@w0&qmIh}<J+RRVtl-#FgXMc3
zPO!Jdz%j=NPT2C`j3>&#pu`ClWdNsHNHNI;wwjZHL4yaJkr==+BMR2R2~IX#V3Q@l
HX<i%v+>1>u

literal 0
HcmV?d00001

diff --git a/tests/test.js b/tests/test.js
index bcdf8fc..d23bc15 100644
--- a/tests/test.js
+++ b/tests/test.js
@@ -6,7 +6,7 @@ var fs = require('fs');
 var path = require('path');
 var should = require('should');
 
-const FILE = path.join(__dirname, 'test.wot');
+const FILE = path.join(__dirname, 'g1_genesis.bin');
 const X_PERCENT = 1.0;
 const _100_PERCENT = 1.0;
 const MAX_DISTANCE_1 = 1;
@@ -19,29 +19,19 @@ const FROM_2_LINKS_SENTRIES = 2;
 const FROM_3_LINKS_SENTRIES = 3;
 const __OUTDISTANCED__ = true;
 const __OK__ = false;
-const MEMORY_MODE = true;
-const FILE_MODE = false;
 
-testSuite("MEMORY", MEMORY_MODE);
+testSuite();
 
-function testSuite(title, mode) {
+function testSuite() {
     function newInstance(launchTests) {
         return () => {
-            if (mode === FILE_MODE) {
-                let wot = addon.newFileInstance(FILE);
-                launchTests(wot, () => {
-                    wot.clear();
-                    wot.setMaxCert(3);
-                });
-            } else {
-                let wot = addon.newMemoryInstance(3);
-                launchTests(wot, () => {});
-            }
+            let wot = addon.newMemoryInstance(3);
+            launchTests(wot);
         }
     }
 
-    describe(title, () => {
-        describe('Basic operations', newInstance((wot, cleanInstance) => {
+    describe("wotb-rs binding tests", () => {
+        describe('Basic operations', newInstance((wot) => {
 
             it('should have an instanceID zero', function() {
                 assert.equal(wot.instanceID, 0)
@@ -264,14 +254,11 @@ function testSuite(title, mode) {
                 should.equal(wot2.instanceID, 0);
                 wot2.clear()
             });
-
-          after(cleanInstance);
         }));
 
-        describe('Building a larger WoT', newInstance((wot, cleanInstance) => {
+        describe('Building a larger WoT', newInstance((wot) => {
 
             before(() => {
-              cleanInstance();
               /**
                * We build WoT:
                *
@@ -483,6 +470,46 @@ function testSuite(title, mode) {
                   should.equal(wot.isOutdistanced(2, FROM_3_LINKS_SENTRIES, MAX_DISTANCE_5, 0.01), __OK__);
                 });
             });
+
+            describe('testing write in file', () => {
+                it('should can write in file', function() {
+                    wot.setFilePath("test.bin");
+                    assert.equal(wot.write(), true)
+                });
+            });
+        }));
+
+        describe('tests g1 genesis wot', newInstance((wot) => {
+
+            before(() => {
+                wot.clear();
+                wot = addon.newFileInstance(FILE, 100);
+            });
+
+            it('should have an instanceID zero', function() {
+                assert.equal(wot.instanceID, 0)
+            });
+
+            it('should have 100 max links', function() {
+                assert.equal(wot.getMaxCert(), 100)
+            });
+
+            it('should have a wot size of 59', function() {
+                should.equal(wot.getWoTSize(), 59);
+            });
+
+            it('should have only enabled members', function() {
+                should.equal(wot.getEnabled().length, 59);
+                should.equal(wot.getDisabled().length, 0);
+            });
+
+            it('should have 48 sentries', function() {
+                should.equal(wot.getSentries(FROM_3_LINKS_SENTRIES).length, 48);
+            });
+
+            after(() => {
+                wot.clear();
+            });
         }));
     });
 }
\ No newline at end of file
-- 
GitLab