diff --git a/.travis.yml b/.travis.yml
index fafacbd5a..83b21d840 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,4 +8,6 @@ before_script:
script:
- "jshint *.js lib"
after_script:
- - npm run-script gulp
+ - npm run-script build
+ - npm test
+
diff --git a/dist/ethereum.js b/dist/ethereum.js
index 26de2c02e..cf2492997 100644
--- a/dist/ethereum.js
+++ b/dist/ethereum.js
@@ -277,6 +277,7 @@ module.exports = {
methodSignature: methodSignature
};
+
},{}],2:[function(require,module,exports){
/*
This file is part of ethereum.js.
diff --git a/dist/ethereum.js.map b/dist/ethereum.js.map
index bb29b435d..e875a0408 100644
--- a/dist/ethereum.js.map
+++ b/dist/ethereum.js.map
@@ -12,12 +12,12 @@
"index.js"
],
"names": [],
- "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7fA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA",
+ "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7fA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA",
"file": "generated.js",
"sourceRoot": "",
"sourcesContent": [
"(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o.\n*/\n/** @file abi.js\n * @authors:\n * Marek Kotewicz \n * Gav Wood \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var web3 = require('./web3'); // jshint ignore:line\n*/}\n\n// TODO: make these be actually accurate instead of falling back onto JS's doubles.\nvar hexToDec = function (hex) {\n return parseInt(hex, 16).toString();\n};\n\nvar decToHex = function (dec) {\n return parseInt(dec).toString(16);\n};\n\nvar findIndex = function (array, callback) {\n var end = false;\n var i = 0;\n for (; i < array.length && !end; i++) {\n end = callback(array[i]);\n }\n return end ? i - 1 : -1;\n};\n\nvar findMethodIndex = function (json, methodName) {\n return findIndex(json, function (method) {\n return method.name === methodName;\n });\n};\n\nvar padLeft = function (string, chars) {\n return new Array(chars - string.length + 1).join(\"0\") + string;\n};\n\nvar calcBitPadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n return parseInt(value) / 8;\n};\n\nvar calcBytePadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n return parseInt(value);\n};\n\nvar calcRealPadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n var sizes = value.split('x');\n for (var padding = 0, i = 0; i < sizes; i++) {\n padding += (sizes[i] / 8);\n }\n return padding;\n};\n\nvar setupInputTypes = function () {\n \n var prefixedType = function (prefix, calcPadding) {\n return function (type, value) {\n var expected = prefix;\n if (type.indexOf(expected) !== 0) {\n return false;\n }\n\n var padding = calcPadding(type, expected);\n if (typeof value === \"number\")\n value = value.toString(16);\n else if (typeof value === \"string\")\n value = web3.toHex(value); \n else if (value.indexOf('0x') === 0)\n value = value.substr(2);\n else\n value = (+value).toString(16);\n return padLeft(value, padding * 2);\n };\n };\n\n var namedType = function (name, padding, formatter) {\n return function (type, value) {\n if (type !== name) {\n return false;\n }\n\n return padLeft(formatter ? formatter(value) : value, padding * 2);\n };\n };\n\n var formatBool = function (value) {\n return value ? '0x1' : '0x0';\n };\n\n return [\n prefixedType('uint', calcBitPadding),\n prefixedType('int', calcBitPadding),\n prefixedType('hash', calcBitPadding),\n prefixedType('string', calcBytePadding),\n prefixedType('real', calcRealPadding),\n prefixedType('ureal', calcRealPadding),\n namedType('address', 20),\n namedType('bool', 1, formatBool),\n ];\n};\n\nvar inputTypes = setupInputTypes();\n\nvar toAbiInput = function (json, methodName, params) {\n var bytes = \"\";\n var index = findMethodIndex(json, methodName);\n\n if (index === -1) {\n return;\n }\n\n var method = json[index];\n\n for (var i = 0; i < method.inputs.length; i++) {\n var found = false;\n for (var j = 0; j < inputTypes.length && !found; j++) {\n found = inputTypes[j](method.inputs[i].type, params[i]);\n }\n if (!found) {\n console.error('unsupported json type: ' + method.inputs[i].type);\n }\n bytes += found;\n }\n return bytes;\n};\n\nvar setupOutputTypes = function () {\n\n var prefixedType = function (prefix, calcPadding) {\n return function (type) {\n var expected = prefix;\n if (type.indexOf(expected) !== 0) {\n return -1;\n }\n\n var padding = calcPadding(type, expected);\n return padding * 2;\n };\n };\n\n var namedType = function (name, padding) {\n return function (type) {\n return name === type ? padding * 2 : -1;\n };\n };\n\n var formatInt = function (value) {\n return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value);\n };\n\n var formatHash = function (value) {\n return \"0x\" + value;\n };\n\n var formatBool = function (value) {\n return value === '1' ? true : false;\n };\n\n var formatString = function (value) {\n return web3.toAscii(value);\n };\n\n return [\n { padding: prefixedType('uint', calcBitPadding), format: formatInt },\n { padding: prefixedType('int', calcBitPadding), format: formatInt },\n { padding: prefixedType('hash', calcBitPadding), format: formatHash },\n { padding: prefixedType('string', calcBytePadding), format: formatString },\n { padding: prefixedType('real', calcRealPadding), format: formatInt },\n { padding: prefixedType('ureal', calcRealPadding), format: formatInt },\n { padding: namedType('address', 20) },\n { padding: namedType('bool', 1), format: formatBool }\n ];\n};\n\nvar outputTypes = setupOutputTypes();\n\nvar fromAbiOutput = function (json, methodName, output) {\n var index = findMethodIndex(json, methodName);\n\n if (index === -1) {\n return;\n }\n\n output = output.slice(2);\n\n var result = [];\n var method = json[index];\n for (var i = 0; i < method.outputs.length; i++) {\n var padding = -1;\n for (var j = 0; j < outputTypes.length && padding === -1; j++) {\n padding = outputTypes[j].padding(method.outputs[i].type);\n }\n\n if (padding === -1) {\n // not found output parsing\n continue;\n }\n var res = output.slice(0, padding);\n var formatter = outputTypes[j - 1].format;\n result.push(formatter ? formatter(res) : (\"0x\" + res));\n output = output.slice(padding);\n }\n\n return result;\n};\n\nvar inputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n parser[method.name] = function () {\n var params = Array.prototype.slice.call(arguments);\n return toAbiInput(json, method.name, params);\n };\n });\n\n return parser;\n};\n\nvar outputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n parser[method.name] = function (output) {\n return fromAbiOutput(json, method.name, output);\n };\n });\n\n return parser;\n};\n\nvar methodSignature = function (json, name) {\n var method = json[findMethodIndex(json, name)];\n var result = name + '(';\n var inputTypes = method.inputs.map(function (inp) {\n return inp.type;\n });\n result += inputTypes.join(',');\n result += ')';\n\n return web3.sha3(web3.fromAscii(result));\n};\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n methodSignature: methodSignature\n};\n",
+ "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file abi.js\n * @authors:\n * Marek Kotewicz \n * Gav Wood \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var web3 = require('./web3'); // jshint ignore:line\n*/}\n\n// TODO: make these be actually accurate instead of falling back onto JS's doubles.\nvar hexToDec = function (hex) {\n return parseInt(hex, 16).toString();\n};\n\nvar decToHex = function (dec) {\n return parseInt(dec).toString(16);\n};\n\nvar findIndex = function (array, callback) {\n var end = false;\n var i = 0;\n for (; i < array.length && !end; i++) {\n end = callback(array[i]);\n }\n return end ? i - 1 : -1;\n};\n\nvar findMethodIndex = function (json, methodName) {\n return findIndex(json, function (method) {\n return method.name === methodName;\n });\n};\n\nvar padLeft = function (string, chars) {\n return new Array(chars - string.length + 1).join(\"0\") + string;\n};\n\nvar calcBitPadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n return parseInt(value) / 8;\n};\n\nvar calcBytePadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n return parseInt(value);\n};\n\nvar calcRealPadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n var sizes = value.split('x');\n for (var padding = 0, i = 0; i < sizes; i++) {\n padding += (sizes[i] / 8);\n }\n return padding;\n};\n\nvar setupInputTypes = function () {\n \n var prefixedType = function (prefix, calcPadding) {\n return function (type, value) {\n var expected = prefix;\n if (type.indexOf(expected) !== 0) {\n return false;\n }\n\n var padding = calcPadding(type, expected);\n if (typeof value === \"number\")\n value = value.toString(16);\n else if (typeof value === \"string\")\n value = web3.toHex(value); \n else if (value.indexOf('0x') === 0)\n value = value.substr(2);\n else\n value = (+value).toString(16);\n return padLeft(value, padding * 2);\n };\n };\n\n var namedType = function (name, padding, formatter) {\n return function (type, value) {\n if (type !== name) {\n return false;\n }\n\n return padLeft(formatter ? formatter(value) : value, padding * 2);\n };\n };\n\n var formatBool = function (value) {\n return value ? '0x1' : '0x0';\n };\n\n return [\n prefixedType('uint', calcBitPadding),\n prefixedType('int', calcBitPadding),\n prefixedType('hash', calcBitPadding),\n prefixedType('string', calcBytePadding),\n prefixedType('real', calcRealPadding),\n prefixedType('ureal', calcRealPadding),\n namedType('address', 20),\n namedType('bool', 1, formatBool),\n ];\n};\n\nvar inputTypes = setupInputTypes();\n\nvar toAbiInput = function (json, methodName, params) {\n var bytes = \"\";\n var index = findMethodIndex(json, methodName);\n\n if (index === -1) {\n return;\n }\n\n var method = json[index];\n\n for (var i = 0; i < method.inputs.length; i++) {\n var found = false;\n for (var j = 0; j < inputTypes.length && !found; j++) {\n found = inputTypes[j](method.inputs[i].type, params[i]);\n }\n if (!found) {\n console.error('unsupported json type: ' + method.inputs[i].type);\n }\n bytes += found;\n }\n return bytes;\n};\n\nvar setupOutputTypes = function () {\n\n var prefixedType = function (prefix, calcPadding) {\n return function (type) {\n var expected = prefix;\n if (type.indexOf(expected) !== 0) {\n return -1;\n }\n\n var padding = calcPadding(type, expected);\n return padding * 2;\n };\n };\n\n var namedType = function (name, padding) {\n return function (type) {\n return name === type ? padding * 2 : -1;\n };\n };\n\n var formatInt = function (value) {\n return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value);\n };\n\n var formatHash = function (value) {\n return \"0x\" + value;\n };\n\n var formatBool = function (value) {\n return value === '1' ? true : false;\n };\n\n var formatString = function (value) {\n return web3.toAscii(value);\n };\n\n return [\n { padding: prefixedType('uint', calcBitPadding), format: formatInt },\n { padding: prefixedType('int', calcBitPadding), format: formatInt },\n { padding: prefixedType('hash', calcBitPadding), format: formatHash },\n { padding: prefixedType('string', calcBytePadding), format: formatString },\n { padding: prefixedType('real', calcRealPadding), format: formatInt },\n { padding: prefixedType('ureal', calcRealPadding), format: formatInt },\n { padding: namedType('address', 20) },\n { padding: namedType('bool', 1), format: formatBool }\n ];\n};\n\nvar outputTypes = setupOutputTypes();\n\nvar fromAbiOutput = function (json, methodName, output) {\n var index = findMethodIndex(json, methodName);\n\n if (index === -1) {\n return;\n }\n\n output = output.slice(2);\n\n var result = [];\n var method = json[index];\n for (var i = 0; i < method.outputs.length; i++) {\n var padding = -1;\n for (var j = 0; j < outputTypes.length && padding === -1; j++) {\n padding = outputTypes[j].padding(method.outputs[i].type);\n }\n\n if (padding === -1) {\n // not found output parsing\n continue;\n }\n var res = output.slice(0, padding);\n var formatter = outputTypes[j - 1].format;\n result.push(formatter ? formatter(res) : (\"0x\" + res));\n output = output.slice(padding);\n }\n\n return result;\n};\n\nvar inputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n parser[method.name] = function () {\n var params = Array.prototype.slice.call(arguments);\n return toAbiInput(json, method.name, params);\n };\n });\n\n return parser;\n};\n\nvar outputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n parser[method.name] = function (output) {\n return fromAbiOutput(json, method.name, output);\n };\n });\n\n return parser;\n};\n\nvar methodSignature = function (json, name) {\n var method = json[findMethodIndex(json, name)];\n var result = name + '(';\n var inputTypes = method.inputs.map(function (inp) {\n return inp.type;\n });\n result += inputTypes.join(',');\n result += ')';\n\n return web3.sha3(web3.fromAscii(result));\n};\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n methodSignature: methodSignature\n};\n\n",
"/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file autoprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\n/*\n * @brief if qt object is available, uses QtProvider,\n * if not tries to connect over websockets\n * if it fails, it uses HttpRpcProvider\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var WebSocket = require('ws'); // jshint ignore:line\n var web3 = require('./web3'); // jshint ignore:line\n*/}\n\nvar AutoProvider = function (userOptions) {\n if (web3.haveProvider()) {\n return;\n }\n\n // before we determine what provider we are, we have to cache request\n this.sendQueue = [];\n this.onmessageQueue = [];\n\n if (navigator.qt) {\n this.provider = new web3.providers.QtProvider();\n return;\n }\n\n userOptions = userOptions || {};\n var options = {\n httprpc: userOptions.httprpc || 'http://localhost:8080',\n websockets: userOptions.websockets || 'ws://localhost:40404/eth'\n };\n\n var self = this;\n var closeWithSuccess = function (success) {\n ws.close();\n if (success) {\n self.provider = new web3.providers.WebSocketProvider(options.websockets);\n } else {\n self.provider = new web3.providers.HttpRpcProvider(options.httprpc);\n self.poll = self.provider.poll.bind(self.provider);\n }\n self.sendQueue.forEach(function (payload) {\n self.provider(payload);\n });\n self.onmessageQueue.forEach(function (handler) {\n self.provider.onmessage = handler;\n });\n };\n\n var ws = new WebSocket(options.websockets);\n\n ws.onopen = function() {\n closeWithSuccess(true);\n };\n\n ws.onerror = function() {\n closeWithSuccess(false);\n };\n};\n\nAutoProvider.prototype.send = function (payload) {\n if (this.provider) {\n this.provider.send(payload);\n return;\n }\n this.sendQueue.push(payload);\n};\n\nObject.defineProperty(AutoProvider.prototype, 'onmessage', {\n set: function (handler) {\n if (this.provider) {\n this.provider.onmessage = handler;\n return;\n }\n this.onmessageQueue.push(handler);\n }\n});\n\nmodule.exports = AutoProvider;\n",
"/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file contract.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var web3 = require('./web3'); // jshint ignore:line\n*/}\n\nvar abi = require('./abi');\n\n// method signature length in bytes\nvar ETH_METHOD_SIGNATURE_LENGTH = 4;\n\nvar contract = function (address, desc) {\n var inputParser = abi.inputParser(desc);\n var outputParser = abi.outputParser(desc);\n\n var contract = {};\n\n desc.forEach(function (method) {\n contract[method.name] = function () {\n var params = Array.prototype.slice.call(arguments);\n var parsed = inputParser[method.name].apply(null, params);\n\n var onSuccess = function (result) {\n return outputParser[method.name](result);\n };\n\n return {\n call: function (extra) {\n extra = extra || {};\n extra.to = address;\n return abi.methodSignature(desc, method.name).then(function (signature) {\n extra.data = signature.slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2) + parsed;\n return web3.eth.call(extra).then(onSuccess);\n });\n },\n transact: function (extra) {\n extra = extra || {};\n extra.to = address;\n extra.data = parsed;\n return web3.eth.transact(extra).then(onSuccess);\n }\n };\n };\n });\n\n return contract;\n};\n\nmodule.exports = contract;\n",
"/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httprpc.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\n*/}\n\nvar HttpRpcProvider = function (host) {\n this.handlers = [];\n this.host = host;\n};\n\nfunction formatJsonRpcObject(object) {\n return {\n jsonrpc: '2.0',\n method: object.call,\n params: object.args,\n id: object._id\n };\n}\n\nfunction formatJsonRpcMessage(message) {\n var object = JSON.parse(message);\n\n return {\n _id: object.id,\n data: object.result,\n error: object.error\n };\n}\n\nHttpRpcProvider.prototype.sendRequest = function (payload, cb) {\n var data = formatJsonRpcObject(payload);\n\n var request = new XMLHttpRequest();\n request.open(\"POST\", this.host, true);\n request.send(JSON.stringify(data));\n request.onreadystatechange = function () {\n if (request.readyState === 4 && cb) {\n cb(request);\n }\n };\n};\n\nHttpRpcProvider.prototype.send = function (payload) {\n var self = this;\n this.sendRequest(payload, function (request) {\n self.handlers.forEach(function (handler) {\n handler.call(self, formatJsonRpcMessage(request.responseText));\n });\n });\n};\n\nHttpRpcProvider.prototype.poll = function (payload, id) {\n var self = this;\n this.sendRequest(payload, function (request) {\n var parsed = JSON.parse(request.responseText);\n if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) {\n return;\n }\n self.handlers.forEach(function (handler) {\n handler.call(self, {_event: payload.call, _id: id, data: parsed.result});\n });\n });\n};\n\nObject.defineProperty(HttpRpcProvider.prototype, \"onmessage\", {\n set: function (handler) {\n this.handlers.push(handler);\n }\n});\n\nmodule.exports = HttpRpcProvider;\n",
diff --git a/lib/abi.js b/lib/abi.js
index 99d2ba932..86cd99cf4 100644
--- a/lib/abi.js
+++ b/lib/abi.js
@@ -275,3 +275,4 @@ module.exports = {
outputParser: outputParser,
methodSignature: methodSignature
};
+
diff --git a/package.json b/package.json
index fc34be487..b4f180d10 100644
--- a/package.json
+++ b/package.json
@@ -25,12 +25,14 @@
"jshint": ">=2.5.0",
"uglifyify": "^2.6.0",
"unreachable-branch-transform": "^0.1.0",
- "vinyl-source-stream": "^1.0.0"
+ "vinyl-source-stream": "^1.0.0",
+ "mocha": ">=2.1.0"
},
"scripts": {
"build": "gulp",
"watch": "gulp watch",
- "lint": "gulp lint"
+ "lint": "gulp lint",
+ "test": "mocha"
},
"repository": {
"type": "git",
diff --git a/test/abi.parsers.js b/test/abi.parsers.js
new file mode 100644
index 000000000..06a77fb86
--- /dev/null
+++ b/test/abi.parsers.js
@@ -0,0 +1,37 @@
+var assert = require('assert');
+var abi = require('../lib/abi.js');
+
+describe('abi', function() {
+ describe('inputParser', function() {
+ it('should parse ...', function() {
+
+ var desc = [{
+ "name": "multiply",
+ "inputs": [
+ {
+ "name": "a",
+ "type": "uint256"
+ }
+ ],
+ "outputs": [
+ {
+ "name": "d",
+ "type": "uint256"
+ }
+ ]
+ }];
+
+ var iParser = abi.inputParser(desc);
+ assert.equal(iParser.multiply(1), "0x000000000000000000000000000000000000000000000000000000000000000001");
+
+ });
+ });
+
+
+ describe('outputParser', function() {
+ it('parse ...', function() {
+
+ });
+ });
+});
+
diff --git a/test/db.methods.js b/test/db.methods.js
new file mode 100644
index 000000000..b4abfc4d7
--- /dev/null
+++ b/test/db.methods.js
@@ -0,0 +1,18 @@
+require('es6-promise').polyfill();
+
+var assert = require('assert');
+var web3 = require('../index.js');
+var u = require('./utils.js');
+web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
+
+describe('web3', function() {
+ describe('db', function() {
+ it('should have all methods implemented', function() {
+ u.methodExists(web3.db, 'put');
+ u.methodExists(web3.db, 'get');
+ u.methodExists(web3.db, 'putString');
+ u.methodExists(web3.db, 'getString');
+ });
+ });
+});
+
diff --git a/test/eth.methods.js b/test/eth.methods.js
new file mode 100644
index 000000000..7190b27d2
--- /dev/null
+++ b/test/eth.methods.js
@@ -0,0 +1,42 @@
+require('es6-promise').polyfill();
+
+var assert = require('assert');
+var web3 = require('../index.js');
+var u = require('./utils.js');
+web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
+
+describe('web3', function() {
+ describe('eth', function() {
+ it('should have all methods implemented', function() {
+ u.methodExists(web3.eth, 'balanceAt');
+ u.methodExists(web3.eth, 'stateAt');
+ u.methodExists(web3.eth, 'storageAt');
+ u.methodExists(web3.eth, 'countAt');
+ u.methodExists(web3.eth, 'codeAt');
+ u.methodExists(web3.eth, 'transact');
+ u.methodExists(web3.eth, 'call');
+ u.methodExists(web3.eth, 'block');
+ u.methodExists(web3.eth, 'transaction');
+ u.methodExists(web3.eth, 'uncle');
+ u.methodExists(web3.eth, 'compilers');
+ u.methodExists(web3.eth, 'lll');
+ u.methodExists(web3.eth, 'solidity');
+ u.methodExists(web3.eth, 'serpent');
+ u.methodExists(web3.eth, 'logs');
+ });
+
+ it('should have all properties implemented', function () {
+ u.propertyExists(web3.eth, 'coinbase');
+ u.propertyExists(web3.eth, 'listening');
+ u.propertyExists(web3.eth, 'mining');
+ u.propertyExists(web3.eth, 'gasPrice');
+ u.propertyExists(web3.eth, 'account');
+ u.propertyExists(web3.eth, 'accounts');
+ u.propertyExists(web3.eth, 'peerCount');
+ u.propertyExists(web3.eth, 'defaultBlock');
+ u.propertyExists(web3.eth, 'number');
+ });
+ });
+});
+
+
diff --git a/test/mocha.opts b/test/mocha.opts
new file mode 100644
index 000000000..b2db8d5a7
--- /dev/null
+++ b/test/mocha.opts
@@ -0,0 +1,2 @@
+--reporter Spec
+
diff --git a/test/shh.methods.js b/test/shh.methods.js
new file mode 100644
index 000000000..08f573a3c
--- /dev/null
+++ b/test/shh.methods.js
@@ -0,0 +1,19 @@
+require('es6-promise').polyfill();
+
+var assert = require('assert');
+var web3 = require('../index.js');
+var u = require('./utils.js');
+web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
+
+describe('web3', function() {
+ describe('shh', function() {
+ it('should have all methods implemented', function() {
+ u.methodExists(web3.shh, 'post');
+ u.methodExists(web3.shh, 'newIdentity');
+ u.methodExists(web3.shh, 'haveIdentity');
+ u.methodExists(web3.shh, 'newGroup');
+ u.methodExists(web3.shh, 'addToGroup');
+ });
+ });
+});
+
diff --git a/test/utils.js b/test/utils.js
new file mode 100644
index 000000000..4c508da67
--- /dev/null
+++ b/test/utils.js
@@ -0,0 +1,15 @@
+var assert = require('assert');
+
+var methodExists = function (object, method) {
+ assert.equal('function', typeof object[method], 'method ' + method + ' is not implemented');
+};
+
+var propertyExists = function (object, property) {
+ assert.equal('object', typeof object[property], 'property ' + property + ' is not implemented');
+};
+
+module.exports = {
+ methodExists: methodExists,
+ propertyExists: propertyExists
+};
+
diff --git a/test/web3.methods.js b/test/web3.methods.js
new file mode 100644
index 000000000..a7e020978
--- /dev/null
+++ b/test/web3.methods.js
@@ -0,0 +1,18 @@
+require('es6-promise').polyfill();
+
+var assert = require('assert');
+var web3 = require('../index.js');
+var u = require('./utils.js');
+web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
+
+describe('web3', function() {
+ it('should have all methods implemented', function() {
+ u.methodExists(web3, 'sha3');
+ u.methodExists(web3, 'toAscii');
+ u.methodExists(web3, 'fromAscii');
+ u.methodExists(web3, 'toFixed');
+ u.methodExists(web3, 'fromFixed');
+ u.methodExists(web3, 'offset');
+ });
+});
+