/* global describe, it */
import chai from "chai";
var expect = chai.expect;
import { ID, Bitfield} from "relativity";

describe("ID", function() {

  chai.Assertion.addMethod('isDisjointFrom', function(idB) {
    var idA = this._obj;

    new chai.Assertion(idA).to.be.instanceof(ID);
    new chai.Assertion(idB).to.be.instanceof(ID);
    this.assert(
      idA.zip(idB).foldUp(function(left, right, value) {
        return left && right && !(value[0] && value[1]);
      }, true),
      "expected #{idA} to be disjoint from #{idB}"
    );
  });

  it("builds leaf ID", function() {
    var l = new ID(1);
    expect(l.leaf()).to.equal(1);
    expect(l.isLeaf(), "is leaf").to.be.true();
    expect(l.left()).to.be.undefined();
  });

  it("builds interior ID", function() {
    var l = new ID([1,0]);
    expect(l.isLeaf(), "not isLeaf").to.be.false();
    expect(l.leaf()).to.be.undefined();
    expect(l.left()).instanceof(ID);
    expect(l.left().leaf()).to.equal(1);
  });


  it("splits into disjoint pieces", function() {
    var i, ids = [new ID(1)].concat(new ID(1).split());
    expect(ids.length);

    for (i=0; i<ids.length; i++) {
      var pieces = ids[i].split();
      expect(pieces[0]).isDisjointFrom(pieces[1]);
    }
  });

  it("can use disjointness tester", function() {
    expect(new ID(1)).not.isDisjointFrom(new ID(1));
    expect(new ID(1)).isDisjointFrom(new ID(0));
    expect(new ID([1,0])).not.isDisjointFrom(new ID([[1,0],0]));
    expect(new ID([1,0])).isDisjointFrom(new ID([[0,0],0]));
  });

  it("supports normalization", function() {
    var cases = [
      {from: 0, to: 0},
      {from: 1, to: 1},
      {from: [0,1], to: [0,1]},
      {from: [0,0], to: 0},
      {from: [1,[0,0]], to: [1,0]},
      {from: [1,[1,1]], to: 1}
    ];
    for (var i=0; i<cases.length; i++) {
      expect(new ID(cases[i].from).normalize().flatten()).to.deep.equal(cases[i].to);
    }
  });

  it("supports sum", function() {
    var cases = [
      {add: 0, to: 0, get: 0},
      {add: 1, to: 1, get: 1},
      {add: 0, to: 1, get: 1},
      {add: [1,0], to: [0, 1], get: 1},
      {add: [0,[0,[0,1]]], to: [[[1,0],0],0], get: [[[1,0],0],[0, [0,1]]]},
      {add: [1,[0,[0,1]]], to: [[[1,0],0],0], get: [1,[0, [0,1]]]},
      {add: [1,[0,[0,1]]], to: [1,[0,[1,0]]], get: [1,[0, 1]]}
    ];
    for (var i=0; i<cases.length; i++) {
      expect(new ID(cases[i].add).sum(new ID(cases[i].to)).flatten())
        .to.deep.equal(cases[i].get);
    }
  });

  it("can be packed", function() {
    var i = new ID([[0,1], [[0,1], 0]]);
    var b = new Bitfield(8);
    i.pack(b);
    b.doneWriting();
    expect(b.hex()).to.equal('4723');
    expect(b.asUnicode()).to.equal("⍇");
  });

  it("can be unpacked", function() {
    var b = new Bitfield(8);
    b.write(0x2347, 16);
    b.rewind();
    var i = ID.unpack(b);
    expect(i.flatten()).to.deep.equal([[0,1], [[0,1], 0]]);

    i = ID.unpack(Bitfield.fromUnicode("⍇"));
    expect(i.flatten()).to.deep.equal([[0,1], [[0,1], 0]]);

  });

});

@@ -2459,32 +2459,33 @@
 );%0A    %7D%0A  %7D);%0A%0A
+%0A
   it(%22can be pac
@@ -2483,24 +2483,35 @@
 an be packed
+ & unpacked
 %22, function(
@@ -2526,233 +2526,239 @@
 var 
-i = new ID(%5B%5B0,1%5D, %5B%5B0,1%5D, 0%5D%5D);%0A    var b = new Bitfield(8);%0A    i.pack(b);%0A    b.doneWriting();%0A    expect(b.hex()).to.equal('4723');%0A    expect(b.asUnicode()).to.equal(%22%E2%8D%87%22);%0A  %7D);%0A%0A  it(%22can be unpacked%22, function(
+examples = %5B%0A      %7B id: 0 %7D,%0A      %7B id: 1 %7D,%0A      %7B id: %5B 0, 1 %5D %7D,%0A      %7B id: %5B 1, 0 %5D %7D,%0A      %7B id: %5B 1, 1 %5D %7D,%0A      %7B id: %5B 1, %5B 0, 1%5D %5D %7D,%0A      %7B id: %5B%5B1, 0%5D, 0 %5D %7D%0A    %5D;%0A    for (var i=0; i%3Cexamples.length; i++
 ) %7B%0A    
 var 
@@ -2757,169 +2757,163 @@
     
+  
 var 
-b
+id
  = new 
-Bitfield(8);%0A    b.write(0x2347, 16);%0A    b.rewind();%0A    var i = ID.unpack(b);%0A    expect(i.flatten()).to.deep.equal(%5B%5B0,1%5D, %5B%5B0,1%5D, 0%5D%5D
+ID(examples%5Bi%5D.id);%0A      var bitfield = new Bitfield(256);%0A      id.pack(bitfield);%0A      bitfield = bitfield.dup().rewind(
 );%0A
-%0A
     
-i = 
+  expect(
 ID.u
@@ -2922,48 +2922,17 @@
 ack(
-B
+b
 itfield
-.fromUnicode(%22%E2%8D%87%22));%0A    expect(i
+)
 .fla
@@ -2957,30 +2957,30 @@
 ual(
-%5B%5B0,1%5D, %5B%5B0,1%5D, 0%5D%5D);%0A
+examples%5Bi%5D.id);%0A    %7D
 %0A  %7D

test id pack