I have been neglecting the test suite in the Dart version of the ICE Code Editor. I still have the original four specs that I wrote for it and they still pass. The code still passes
dart_analyzer. So it ought to be in pretty decent shape. Still, I need to go back to add some tests to catch regressions and the like. But I'll leave that for another day. Maybe even for a #pairwithme session.
Tonight I am going to start working through new code, but I hope to be better about driving it with tests. The next feature that I want to add to ICE is the ability to interface with localStorage. Before I do that, I need to be able to deflate and inflate compressed data that will be stored therein. A little while back, I spiked some exploratory code to find that Dart could use its Zlib package to work with this data. Unfortunately, I also found that it was only capable of doing so on the server. Since this needs to work in the browser, I need to js-interop with the legacy JavaScript.
From the JavaScript version, I know how the string
"Howdy, Bob!" should look when it is encoded (gzip'd and mime64 encoded). This makes it easy to write two tests:import 'package:unittest/unittest.dart';
import 'package:ice_code_editor/store.dart';
import 'dart:html';
main() {
group("gzipping", () {
test("it can encode text", (){
expect(Store.encode("Howdy, Bob!"), equals("88gvT6nUUXDKT1IEAA=="));
});
test("it can decode as text", (){
expect(Store.decode("88gvT6nUUXDKT1IEAA=="), equals("Howdy, Bob!"));
});
});
}From there, the tests drive me. First up, I need to change the message indicating that I do not have a store.dart file:Failed to load a file file:///home/chris/repos/ice-code-editor/test/packages/ice_code_editor/store.dart store_test.dart:-1 GET file:///home/chris/repos/ice-code-editor/test/packages/ice_code_editor/store.dartAfter fixing that, my tests tell me that I need a
Store class, then that I need static methods encode and decode. This leaves me with:library ice;
class Store {
static String encode(String string) {
}
static String decode(String string) {
}
}At this point, the message that I need to change is:FAIL: gzipping it can encode text
Expected: '88gvT6nUUXDKT1IEAA=='
but: expected String:'88gvT6nUUXDKT1IEAA==' but was null:<null>.Finally, to make that pass, I use a bit of knowledge left over from the spike. The RawDeflate.deflate() call from Dart looks like:js.context.RawDeflate.deflate(string) thanks to the magic of js-interop. That returns a string of gzip'd data. I then use CryptoUtils.bytesToBase64() from the dart:crypto package (why is base64 encoding in dart:crypto, but zlib is not?) package to base64 encode the gzip compressed data. The end result that make my test pass is:library ice;
import 'dart:crypto';
import 'package:js/js.dart' as js;
class Store {
static String encode(String string) {
var gzip = js.context.RawDeflate.deflate(string);
return CryptoUtils.bytesToBase64(gzip.codeUnits);
}
static String decode(String string) {
}
}
To support decoding, I implement the reverse as:library ice;
import 'dart:crypto';
import 'package:js/js.dart' as js;
class Store {
static String encode(String string) {
var gzip = js.context.RawDeflate.deflate(string);
return CryptoUtils.bytesToBase64(gzip.codeUnits);
}
static String decode(String string) {
var bytes = CryptoUtils.base64StringToBytes(string);
var gzip = new String.fromCharCodes(bytes);
return js.context.RawDeflate.inflate(gzip);
}
}With that, I have two passing tests that will let me work with existing data stored from the JavaScript version of the code editor. This seems like a fine stopping point for tonight. At least until my next #pairwithme session!Day #745
No comments:
Post a Comment