diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 0000000..3963284 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,17 @@ +[ignore] +.*/node_modules/.* +.*/dist/.* +.*/test.js +.*/adler32.js + +.*/bits/.* +.*/ctest/.* +.*/misc/.* +.*/perf/.* + +[include] +adler32.flow.js + +[libs] + +[options] diff --git a/.gitignore b/.gitignore index 4247ef3..4385eea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ node_modules +test_files/*.py +test_files/*.js +test_files/baseline* misc/coverage.html misc/*/ diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..5d3cd6c --- /dev/null +++ b/.jshintrc @@ -0,0 +1,5 @@ +{ + "bitwise": false, + "curly": false +} + diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..ab99f52 --- /dev/null +++ b/.npmignore @@ -0,0 +1,14 @@ +node_modules +misc/ +perf/ +bits/ +ctest/ +test_files/ +test.js +.travis.yml +.jscs.json +.jshintrc +.flowconfig +.npmignore +perf.txt +Makefile diff --git a/.travis.yml b/.travis.yml index 04a2f37..fdd2eb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,14 @@ language: node_js node_js: - - "0.11" + - "5.0" + - "4.2" + - "0.12" - "0.10" - "0.8" before_install: + - "npm install -g npm@next" - "npm install -g mocha" + - "npm install codepage" - "npm install blanket" - "npm install coveralls mocha-lcov-reporter" after_success: diff --git a/LICENSE b/LICENSE index c004c7c..9fd9d56 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2014 SheetJS +Copyright (C) 2014-present SheetJS Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/Makefile b/Makefile index bbf41b4..d8cbb7d 100644 --- a/Makefile +++ b/Makefile @@ -1,32 +1,47 @@ LIB=adler32 +REQS= +ADDONS= +AUXTARGETS= + +ULIB=$(shell echo $(LIB) | tr a-z A-Z) DEPS=$(sort $(wildcard bits/*.js)) TARGET=$(LIB).js -$(TARGET): $(DEPS) +.PHONY: all +all: $(TARGET) $(AUXTARGETS) + +$(TARGET) $(AUXTARGETS): %.js : %.flow.js + node -e 'process.stdout.write(require("fs").readFileSync("$<","utf8").replace(/^\s*\/\*:[^*]*\*\/\s*(\n)?/gm,"").replace(/\/\*:[^*]*\*\//gm,""))' > $@ + +$(LIB).flow.js: $(DEPS) cat $^ | tr -d '\15\32' > $@ - cp -f $@ ctest/ bits/01_version.js: package.json echo "ADLER32.version = '"`grep version package.json | awk '{gsub(/[^0-9a-z\.-]/,"",$$2); print $$2}'`"';" > $@ .PHONY: clean -clean: +clean: clean-baseline rm -f $(TARGET) .PHONY: test mocha -test mocha: test.js - mocha -R spec +test mocha: test.js $(TARGET) baseline + mocha -R spec -t 20000 .PHONY: ctest ctest: cat misc/*.js > ctest/fixtures.js cp -f test.js ctest/test.js - cp -f $(TARGET) ctest/ + cp -f $(TARGET) ctest/ .PHONY: lint -lint: $(TARGET) - jshint --show-non-errors $(TARGET) - jscs $(TARGET) +lint: $(TARGET) $(AUXTARGETS) + jshint --show-non-errors $(TARGET) $(AUXTARGETS) + jshint --show-non-errors package.json + jscs $(TARGET) $(AUXTARGETS) + +.PHONY: flow +flow: lint + flow check --all --show-all-errors .PHONY: cov cov-spin cov: misc/coverage.html @@ -39,11 +54,11 @@ $(COVFMT): cov_%: FMTS=$* make cov misc/coverage.html: $(TARGET) test.js - mocha --require blanket -R html-cov > $@ + mocha --require blanket -R html-cov -t 20000 > $@ .PHONY: coveralls coveralls-spin coveralls: - mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js + mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | ./node_modules/coveralls/bin/coveralls.js coveralls-spin: make coveralls & bash misc/spin.sh $$! @@ -51,3 +66,14 @@ coveralls-spin: .PHONY: perf perf: bash perf/perf.sh + +.PHONY: perf-all +perf-all: + bash misc/perf.sh + +.PHONY: baseline clean-baseline +baseline: + ./misc/make_baseline.sh + +clean-baseline: + rm -f test_files/*.* diff --git a/README.md b/README.md index 5c61f2a..b2da155 100644 --- a/README.md +++ b/README.md @@ -79,9 +79,11 @@ Subtract up to 4 elements for the unicode case. Please consult the attached LICENSE file for details. All rights not explicitly granted by the Apache 2.0 license are reserved by the Original Author. +## Badges + [![Build Status](https://travis-ci.org/SheetJS/js-adler32.svg?branch=master)](https://travis-ci.org/SheetJS/js-adler32) [![Coverage Status](https://coveralls.io/repos/SheetJS/js-adler32/badge.png?branch=master)](https://coveralls.io/r/SheetJS/js-adler32?branch=master) -[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/8827aa40b3fdbca7c7ad0f51c68b3379 "githalytics.com")](http://githalytics.com/SheetJS/js-adler32) +[![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-adler32?pixel)](https://github.com/SheetJS/js-adler32) diff --git a/adler32.flow.js b/adler32.flow.js new file mode 100644 index 0000000..afb2d69 --- /dev/null +++ b/adler32.flow.js @@ -0,0 +1,91 @@ +/* adler32.js (C) 2014-present SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +var ADLER32; +/*:: declare var DO_NOT_EXPORT_ADLER: any; */ +/*:: declare var define: any; */ +(function (factory) { + if(typeof DO_NOT_EXPORT_ADLER === 'undefined') { + if('object' === typeof exports) { + factory(exports); + } else if ('function' === typeof define && define.amd) { + define(function () { + var module = {}; + factory(module); + return module; + }); + } else { + factory(ADLER32 = {}); + } + } else { + factory(ADLER32 = {}); + } +}(function(ADLER32) { +ADLER32.version = '0.3.0'; +/*:: +type ADLER32Type = number; +type ABuf = Array | Buffer; +*/ +/* consult README.md for the magic number */ +/* charCodeAt is the best approach for binary strings */ +var use_buffer = typeof Buffer !== 'undefined'; +function adler32_bstr(bstr/*:string*/)/*:ADLER32Type*/ { + if(bstr.length > 32768) if(use_buffer) return adler32_buf(new Buffer(bstr)); + var a = 1, b = 0, L = bstr.length, M; + for(var i = 0; i < L;) { + M = Math.min(L-i, 3850)+i; + for(;i>>16)+(a&65535)); + b = (15*(b>>>16)+(b&65535)); + } + return ((b%65521) << 16) | (a%65521); +} + +function adler32_buf(buf/*:ABuf*/)/*:ADLER32Type*/ { + var a = 1, b = 0, L = buf.length, M; + for(var i = 0; i < L;) { + M = Math.min(L-i, 3850)+i; + for(;i>>16)+(a&65535)); + b = (15*(b>>>16)+(b&65535)); + } + return ((b%65521) << 16) | (a%65521); +} + +/* much much faster to intertwine utf8 and adler */ +function adler32_str(str/*:string*/)/*:ADLER32Type*/ { + var a = 1, b = 0, L = str.length, M, c, d; + for(var i = 0; i < L;) { + M = Math.min(L-i, 3850); + while(M>0) { + c = str.charCodeAt(i++); + if(c < 0x80) { a += c; b += a; --M; } + else if(c < 0x800) { + a += 192|((c>>6)&31); b += a; --M; + a += 128|(c&63); b += a; --M; + } else if(c >= 0xD800 && c < 0xE000) { + c = (c&1023)+64; d = str.charCodeAt(i++) & 1023; + a += 240|((c>>8)&7); b += a; --M; + a += 128|((c>>2)&63); b += a; --M; + a += 128|((d>>6)&15)|((c&3)<<4); b += a; --M; + a += 128|(d&63); b += a; --M; + } else { + a += 224|((c>>12)&15); b += a; --M; + a += 128|((c>>6)&63); b += a; --M; + a += 128|(c&63); b += a; --M; + } + } + a %= 65521; + b %= 65521; + } + return (b << 16) | a; +} +ADLER32.bstr = adler32_bstr; +ADLER32.buf = adler32_buf; +ADLER32.str = adler32_str; +})); diff --git a/adler32.js b/adler32.js index 0993821..27f7339 100644 --- a/adler32.js +++ b/adler32.js @@ -1,13 +1,29 @@ -/* adler32.js (C) 2014 SheetJS -- http://sheetjs.com */ +/* adler32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ -var ADLER32 = {}; -(function(ADLER32) { -ADLER32.version = '0.2.0'; +var ADLER32; +(function (factory) { + if(typeof DO_NOT_EXPORT_ADLER === 'undefined') { + if('object' === typeof exports) { + factory(exports); + } else if ('function' === typeof define && define.amd) { + define(function () { + var module = {}; + factory(module); + return module; + }); + } else { + factory(ADLER32 = {}); + } + } else { + factory(ADLER32 = {}); + } +}(function(ADLER32) { +ADLER32.version = '0.3.0'; /* consult README.md for the magic number */ /* charCodeAt is the best approach for binary strings */ var use_buffer = typeof Buffer !== 'undefined'; function adler32_bstr(bstr) { - if(bstr.length > 32768) if(use_buffer) return adler32_buf(Buffer(bstr)); + if(bstr.length > 32768) if(use_buffer) return adler32_buf(new Buffer(bstr)); var a = 1, b = 0, L = bstr.length, M; for(var i = 0; i < L;) { M = Math.min(L-i, 3850)+i; @@ -15,8 +31,8 @@ function adler32_bstr(bstr) { a += bstr.charCodeAt(i); b += a; } - a = (15*(a>>>16)+(a&65535)) - b = (15*(b>>>16)+(b&65535)) + a = (15*(a>>>16)+(a&65535)); + b = (15*(b>>>16)+(b&65535)); } return ((b%65521) << 16) | (a%65521); } @@ -29,8 +45,8 @@ function adler32_buf(buf) { a += buf[i]; b += a; } - a = (15*(a>>>16)+(a&65535)) - b = (15*(b>>>16)+(b&65535)) + a = (15*(a>>>16)+(a&65535)); + b = (15*(b>>>16)+(b&65535)); } return ((b%65521) << 16) | (a%65521); } @@ -44,18 +60,18 @@ function adler32_str(str) { c = str.charCodeAt(i++); if(c < 0x80) { a += c; b += a; --M; } else if(c < 0x800) { - a += 192|((c>>6)&31); b += a; --M; - a += 128|(c&63); b += a; --M; + a += 192|((c>>6)&31); b += a; --M; + a += 128|(c&63); b += a; --M; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++) & 1023; - a += 240|((c>>8)&7); b += a; --M; - a += 128|((c>>2)&63); b += a; --M; - a += 128|((d>>6)&15)|(c&3); b += a; --M; - a += 128|(d&63); b += a; --M; + a += 240|((c>>8)&7); b += a; --M; + a += 128|((c>>2)&63); b += a; --M; + a += 128|((d>>6)&15)|((c&3)<<4); b += a; --M; + a += 128|(d&63); b += a; --M; } else { - a += 224|((c>>12)&15); b += a; --M; - a += 128|((c>>6)&63); b += a; --M; - a += 128|(c&63); b += a; --M; + a += 224|((c>>12)&15); b += a; --M; + a += 128|((c>>6)&63); b += a; --M; + a += 128|(c&63); b += a; --M; } } a %= 65521; @@ -66,4 +82,4 @@ function adler32_str(str) { ADLER32.bstr = adler32_bstr; ADLER32.buf = adler32_buf; ADLER32.str = adler32_str; -})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_ADLER === 'undefined' ? exports : ADLER32); +})); diff --git a/bits/00_header.js b/bits/00_header.js index ed0fc19..5835f06 100644 --- a/bits/00_header.js +++ b/bits/00_header.js @@ -1,4 +1,22 @@ -/* adler32.js (C) 2014 SheetJS -- http://sheetjs.com */ +/* adler32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ -var ADLER32 = {}; -(function(ADLER32) { +var ADLER32; +/*:: declare var DO_NOT_EXPORT_ADLER: any; */ +/*:: declare var define: any; */ +(function (factory) { + if(typeof DO_NOT_EXPORT_ADLER === 'undefined') { + if('object' === typeof exports) { + factory(exports); + } else if ('function' === typeof define && define.amd) { + define(function () { + var module = {}; + factory(module); + return module; + }); + } else { + factory(ADLER32 = {}); + } + } else { + factory(ADLER32 = {}); + } +}(function(ADLER32) { diff --git a/bits/01_version.js b/bits/01_version.js index c3dc615..b2df212 100644 --- a/bits/01_version.js +++ b/bits/01_version.js @@ -1 +1 @@ -ADLER32.version = '0.2.0'; +ADLER32.version = '0.3.0'; diff --git a/bits/10_types.js b/bits/10_types.js new file mode 100644 index 0000000..dbd3846 --- /dev/null +++ b/bits/10_types.js @@ -0,0 +1,4 @@ +/*:: +type ADLER32Type = number; +type ABuf = Array | Buffer; +*/ diff --git a/bits/40_adler.js b/bits/40_adler.js index dac4cc8..6d93182 100644 --- a/bits/40_adler.js +++ b/bits/40_adler.js @@ -1,8 +1,8 @@ /* consult README.md for the magic number */ /* charCodeAt is the best approach for binary strings */ var use_buffer = typeof Buffer !== 'undefined'; -function adler32_bstr(bstr) { - if(bstr.length > 32768) if(use_buffer) return adler32_buf(Buffer(bstr)); +function adler32_bstr(bstr/*:string*/)/*:ADLER32Type*/ { + if(bstr.length > 32768) if(use_buffer) return adler32_buf(new Buffer(bstr)); var a = 1, b = 0, L = bstr.length, M; for(var i = 0; i < L;) { M = Math.min(L-i, 3850)+i; @@ -10,13 +10,13 @@ function adler32_bstr(bstr) { a += bstr.charCodeAt(i); b += a; } - a = (15*(a>>>16)+(a&65535)) - b = (15*(b>>>16)+(b&65535)) + a = (15*(a>>>16)+(a&65535)); + b = (15*(b>>>16)+(b&65535)); } return ((b%65521) << 16) | (a%65521); } -function adler32_buf(buf) { +function adler32_buf(buf/*:ABuf*/)/*:ADLER32Type*/ { var a = 1, b = 0, L = buf.length, M; for(var i = 0; i < L;) { M = Math.min(L-i, 3850)+i; @@ -24,14 +24,14 @@ function adler32_buf(buf) { a += buf[i]; b += a; } - a = (15*(a>>>16)+(a&65535)) - b = (15*(b>>>16)+(b&65535)) + a = (15*(a>>>16)+(a&65535)); + b = (15*(b>>>16)+(b&65535)); } return ((b%65521) << 16) | (a%65521); } /* much much faster to intertwine utf8 and adler */ -function adler32_str(str) { +function adler32_str(str/*:string*/)/*:ADLER32Type*/ { var a = 1, b = 0, L = str.length, M, c, d; for(var i = 0; i < L;) { M = Math.min(L-i, 3850); @@ -39,18 +39,18 @@ function adler32_str(str) { c = str.charCodeAt(i++); if(c < 0x80) { a += c; b += a; --M; } else if(c < 0x800) { - a += 192|((c>>6)&31); b += a; --M; - a += 128|(c&63); b += a; --M; + a += 192|((c>>6)&31); b += a; --M; + a += 128|(c&63); b += a; --M; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++) & 1023; - a += 240|((c>>8)&7); b += a; --M; - a += 128|((c>>2)&63); b += a; --M; - a += 128|((d>>6)&15)|(c&3); b += a; --M; - a += 128|(d&63); b += a; --M; + a += 240|((c>>8)&7); b += a; --M; + a += 128|((c>>2)&63); b += a; --M; + a += 128|((d>>6)&15)|((c&3)<<4); b += a; --M; + a += 128|(d&63); b += a; --M; } else { - a += 224|((c>>12)&15); b += a; --M; - a += 128|((c>>6)&63); b += a; --M; - a += 128|(c&63); b += a; --M; + a += 224|((c>>12)&15); b += a; --M; + a += 128|((c>>6)&63); b += a; --M; + a += 128|(c&63); b += a; --M; } } a %= 65521; diff --git a/bits/99_footer.js b/bits/99_footer.js index efe777e..be4600a 100644 --- a/bits/99_footer.js +++ b/bits/99_footer.js @@ -1 +1 @@ -})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_ADLER === 'undefined' ? exports : ADLER32); +})); diff --git a/ctest/adler32.js b/ctest/adler32.js index 0993821..27f7339 100644 --- a/ctest/adler32.js +++ b/ctest/adler32.js @@ -1,13 +1,29 @@ -/* adler32.js (C) 2014 SheetJS -- http://sheetjs.com */ +/* adler32.js (C) 2014-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ -var ADLER32 = {}; -(function(ADLER32) { -ADLER32.version = '0.2.0'; +var ADLER32; +(function (factory) { + if(typeof DO_NOT_EXPORT_ADLER === 'undefined') { + if('object' === typeof exports) { + factory(exports); + } else if ('function' === typeof define && define.amd) { + define(function () { + var module = {}; + factory(module); + return module; + }); + } else { + factory(ADLER32 = {}); + } + } else { + factory(ADLER32 = {}); + } +}(function(ADLER32) { +ADLER32.version = '0.3.0'; /* consult README.md for the magic number */ /* charCodeAt is the best approach for binary strings */ var use_buffer = typeof Buffer !== 'undefined'; function adler32_bstr(bstr) { - if(bstr.length > 32768) if(use_buffer) return adler32_buf(Buffer(bstr)); + if(bstr.length > 32768) if(use_buffer) return adler32_buf(new Buffer(bstr)); var a = 1, b = 0, L = bstr.length, M; for(var i = 0; i < L;) { M = Math.min(L-i, 3850)+i; @@ -15,8 +31,8 @@ function adler32_bstr(bstr) { a += bstr.charCodeAt(i); b += a; } - a = (15*(a>>>16)+(a&65535)) - b = (15*(b>>>16)+(b&65535)) + a = (15*(a>>>16)+(a&65535)); + b = (15*(b>>>16)+(b&65535)); } return ((b%65521) << 16) | (a%65521); } @@ -29,8 +45,8 @@ function adler32_buf(buf) { a += buf[i]; b += a; } - a = (15*(a>>>16)+(a&65535)) - b = (15*(b>>>16)+(b&65535)) + a = (15*(a>>>16)+(a&65535)); + b = (15*(b>>>16)+(b&65535)); } return ((b%65521) << 16) | (a%65521); } @@ -44,18 +60,18 @@ function adler32_str(str) { c = str.charCodeAt(i++); if(c < 0x80) { a += c; b += a; --M; } else if(c < 0x800) { - a += 192|((c>>6)&31); b += a; --M; - a += 128|(c&63); b += a; --M; + a += 192|((c>>6)&31); b += a; --M; + a += 128|(c&63); b += a; --M; } else if(c >= 0xD800 && c < 0xE000) { c = (c&1023)+64; d = str.charCodeAt(i++) & 1023; - a += 240|((c>>8)&7); b += a; --M; - a += 128|((c>>2)&63); b += a; --M; - a += 128|((d>>6)&15)|(c&3); b += a; --M; - a += 128|(d&63); b += a; --M; + a += 240|((c>>8)&7); b += a; --M; + a += 128|((c>>2)&63); b += a; --M; + a += 128|((d>>6)&15)|((c&3)<<4); b += a; --M; + a += 128|(d&63); b += a; --M; } else { - a += 224|((c>>12)&15); b += a; --M; - a += 128|((c>>6)&63); b += a; --M; - a += 128|(c&63); b += a; --M; + a += 224|((c>>12)&15); b += a; --M; + a += 128|((c>>6)&63); b += a; --M; + a += 128|(c&63); b += a; --M; } } a %= 65521; @@ -66,4 +82,4 @@ function adler32_str(str) { ADLER32.bstr = adler32_bstr; ADLER32.buf = adler32_buf; ADLER32.str = adler32_str; -})(typeof exports !== "undefined" && typeof DO_NOT_EXPORT_ADLER === 'undefined' ? exports : ADLER32); +})); diff --git a/ctest/test.js b/ctest/test.js index 9babed8..cfe4f92 100644 --- a/ctest/test.js +++ b/ctest/test.js @@ -4,13 +4,16 @@ if(typeof require !== 'undefined') { assert = require('assert'); describe('source',function(){it('should load',function(){X=require('./');});}); bits = require('./misc/bits.js'); + fs = require("fs"); } else { X = ADLER32; } +function readlines(f) { return fs.readFileSync(f, "ascii").split("\n").filter(function(f) { return !!f; }); } + describe('adler32 bits', function() { bits.forEach(function(i) { var l = i[0].length; var msg = i[0]; - if(l > 20) i[0].substr(0,5) + "...(" + l + ")..." + i[0].substr(-5); + if(l > 20) msg = i[0].substr(0,5) + "...(" + l + ")..." + i[0].substr(-5); it(msg, function() { if(i[2] === 1) assert.equal(X.bstr(i[0]), i[1]|0); assert.equal(X.str(i[0]), i[1]|0); @@ -18,4 +21,20 @@ describe('adler32 bits', function() { }); }); }); - +if(typeof require !== 'undefined') describe("unicode", function() { + if(!fs.existsSync("./test_files/uccat.txt")) return; + var uccat = readlines("./test_files/uccat.txt"); + uccat.forEach(function(cat) { + it("Category " + cat, function() { + if(!fs.existsSync("./test_files/baseline." + cat + ".txt")) return; + var corpus = readlines("./test_files/baseline." + cat + ".txt"); + var uctable = require("./test_files/uctable." + cat + ".js"); + uctable.forEach(function(c, i) { + /* since the baselines are passed via utf8, discard invalid codes */ + if(c.charCodeAt(0) >= 0xD800 && c.charCodeAt(0) < 0xE000) return; + var cc = corpus[i], dd = X.str(c); + assert.equal(dd, cc, ":" + i + ":" + c + ":" + cc + ":" + dd); + }); + }); + }); +}); diff --git a/misc/make_baseline.sh b/misc/make_baseline.sh new file mode 100755 index 0000000..1a59c2a --- /dev/null +++ b/misc/make_baseline.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# make_baseline.sh -- generate baselines for tests +# Copyright (C) 2016-present SheetJS +OUTD=../test_files +CATURL=https://mathias.html5.org/data/unicode/8.0.0/categories/ +CATF=$OUTD/uccat.txt + +ECHORED() { echo -ne '\x1B[0;31m'; echo -n $1; echo -ne '\x1B[0m'; echo; } + +if [ -d misc ]; then cd misc; fi +mkdir -p $OUTD +if [ ! -e $CATF ]; then curl "$CATURL" | grep "code-points" | sed 's/.*="//g;s/-.*//g' > $CATF; fi + +while read line; do + JSF=uctable.${line}.js + PYF=uctable_${line}.py + BLF=baseline.${line}.txt + JSURL="https://mathias.html5.org/data/unicode/format?version=8.0.0&category=${line}&type=symbols&prepend=var+unicode%20%3D%20&append=%3Bif(typeof%20module%20!%3D%3D%20'undefined')%20module.exports%20%3D%20unicode%3B" + if [[ ! -e $OUTD/$JSF || ! -e $OUTD/$PYF || ! -e $OUTD/$BLF ]]; then + ECHORED "Processing ${line}" + if [ ! -e $JSF ]; then + rm -f $PYF $BLF ${PYF}c + echo "Downloading JS" + $PYF + fi + if [ ! -e $BLF ]; then + echo "Building Baseline text" + python make_unicode_adler.py ${line} > baseline.${line}.txt + fi + for i in $JSF $PYF $BLF; do if [ -e $i ]; then mv $i $OUTD/; fi; done + rm -f uctable_${line}.pyc + fi +done < $CATF + diff --git a/misc/make_unicode.njs b/misc/make_unicode.njs new file mode 100644 index 0000000..9d53aa0 --- /dev/null +++ b/misc/make_unicode.njs @@ -0,0 +1,5 @@ +#!/usr/bin/env node +argv = process.argv.slice(2); +var enc = require('codepage').utils.encode; +function arr(x) { return [].slice.call(enc(65001, x)); } +console.log(require('./uctable.' + argv[0]).map(arr)); diff --git a/misc/make_unicode_adler.py b/misc/make_unicode_adler.py new file mode 100644 index 0000000..2440008 --- /dev/null +++ b/misc/make_unicode_adler.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# make_unicode_crc.py -- generate baselines for tests +# Copyright (C) 2016-present SheetJS + +from zlib import adler32 +from array import array +from sys import argv, stderr, exit +from importlib import import_module + +args = argv[1:] + +if len(args) < 1: + print >>stderr, "usage: " + argv[0] + " " + exit(1) + +uctable = import_module("uctable_" + args[0]).uctable + +for z in uctable: + print adler32(array('B', z)); diff --git a/misc/spin.sh b/misc/spin.sh index 9951a57..471dfee 100755 --- a/misc/spin.sh +++ b/misc/spin.sh @@ -1,6 +1,6 @@ #!/bin/bash # spin.sh -- show a spinner (for coverage test) -# Copyright (C) 2014 SheetJS +# Copyright (C) 2014-present SheetJS wpid=$1 delay=1 diff --git a/package.json b/package.json index 4c35387..64b7e5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "adler-32", - "version": "0.2.1", + "version": "0.3.0", "author": "sheetjs", "description": "Pure-JS ADLER-32", "keywords": [ "adler32", "checksum" ], diff --git a/test.js b/test.js index 9babed8..cfe4f92 100644 --- a/test.js +++ b/test.js @@ -4,13 +4,16 @@ if(typeof require !== 'undefined') { assert = require('assert'); describe('source',function(){it('should load',function(){X=require('./');});}); bits = require('./misc/bits.js'); + fs = require("fs"); } else { X = ADLER32; } +function readlines(f) { return fs.readFileSync(f, "ascii").split("\n").filter(function(f) { return !!f; }); } + describe('adler32 bits', function() { bits.forEach(function(i) { var l = i[0].length; var msg = i[0]; - if(l > 20) i[0].substr(0,5) + "...(" + l + ")..." + i[0].substr(-5); + if(l > 20) msg = i[0].substr(0,5) + "...(" + l + ")..." + i[0].substr(-5); it(msg, function() { if(i[2] === 1) assert.equal(X.bstr(i[0]), i[1]|0); assert.equal(X.str(i[0]), i[1]|0); @@ -18,4 +21,20 @@ describe('adler32 bits', function() { }); }); }); - +if(typeof require !== 'undefined') describe("unicode", function() { + if(!fs.existsSync("./test_files/uccat.txt")) return; + var uccat = readlines("./test_files/uccat.txt"); + uccat.forEach(function(cat) { + it("Category " + cat, function() { + if(!fs.existsSync("./test_files/baseline." + cat + ".txt")) return; + var corpus = readlines("./test_files/baseline." + cat + ".txt"); + var uctable = require("./test_files/uctable." + cat + ".js"); + uctable.forEach(function(c, i) { + /* since the baselines are passed via utf8, discard invalid codes */ + if(c.charCodeAt(0) >= 0xD800 && c.charCodeAt(0) < 0xE000) return; + var cc = corpus[i], dd = X.str(c); + assert.equal(dd, cc, ":" + i + ":" + c + ":" + cc + ":" + dd); + }); + }); + }); +}); diff --git a/test_files/uccat.txt b/test_files/uccat.txt new file mode 100644 index 0000000..63fe097 --- /dev/null +++ b/test_files/uccat.txt @@ -0,0 +1,38 @@ +C +Cc +Cf +Cn +Co +Cs +L +LC +Ll +Lm +Lo +Lt +Lu +M +Mc +Me +Mn +N +Nd +Nl +No +P +Pc +Pd +Pe +Pf +Pi +Po +Ps +S +Sc +Sk +Sm +So +Z +Zl +Zp +Zs