<commit_before>'use strict';

describe('Service: match', function () {

  // load the service's module
  beforeEach(module('flowsimUiApp'));

  // instantiate service
  var Match;
  beforeEach(inject(function (_Match_) {
    Match = _Match_;
  }));

  var UInt;
  beforeEach(inject(function (_UInt_) {
    UInt = _UInt_;
  }));

  var ETHERNET;
  beforeEach(inject(function (_ETHERNET_) {
    ETHERNET = _ETHERNET_;
  }));

  var VLAN;
  beforeEach(inject(function (_VLAN_) {
    VLAN = _VLAN_;
  }));

  var MPLS;
  beforeEach(inject(function (_MPLS_) {
    MPLS = _MPLS_;
  }));

  var ARP;
  beforeEach(inject(function (_ARP_) {
    ARP = _ARP_;
  }));

  var UDP;
  beforeEach(inject(function (_UDP_) {
    UDP = _UDP_;
  }));

  var TCP;
  beforeEach(inject(function (_TCP_) {
    TCP = _TCP_;
  }));

  var Context;
  beforeEach(inject(function(_Context_) {
    Context = _Context_;
  }));

  var IPV4;
  beforeEach(inject(function(_IPV4_) {
    IPV4 = _IPV4_;
  }));

  var IPV6;
  beforeEach(inject(function(_IPV6_) {
    IPV6 = _IPV6_;
  }));

  it('Default Match', function() {
    var key = new Context.Key(null, 0);
    var match = new Match.Set();
    expect(match.match(key)).toBe(true);
  });

  it('Ethernet Match', function () {
    expect(!!Match).toBe(true);
    expect(!!ETHERNET).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'eth_src',
        new ETHERNET.MAC.Match(
          null,
          '00:00:00:00:00:00',
          '00:00:00:00:00:00')));

    expect(match.summarize().toString()).toBe('eth');

    match.push(
      new Match.Match(null,
        'eth_dst',
        new ETHERNET.mkMACMatch(
          'ff:ff:ff:ff:ff:ff',
          'ff:ff:ff:ff:ff:ff')));

    expect(match.summarize().toString()).toBe('eth');

    match.push(
      new Match.Match(null,
        'eth_type',
        new ETHERNET.mkTypeMatch('0x0800', '0xffff')));

    expect(match.summarize().toString()).toBe('eth');

    expect(match.match(key)).toBe(false);

    key.eth_src = new ETHERNET.mkMAC('00:00:00:00:00:00');
    key.eth_dst = new ETHERNET.mkMAC('ff:ff:ff:ff:ff:ff');
    key.eth_type = new ETHERNET.mkType(0x0800);

    expect(match.match(key)).toBe(true);

    key.eth_src = new ETHERNET.mkMAC('00:00:00:00:00:01');
    expect(match.match(key)).toBe(true);

    key.eth_type = new ETHERNET.mkType('0x0806');
    expect(match.match(key)).toBe(false);

  });

  it('VLAN Match', function () {
    expect(!!Match).toBe(true);
    expect(!!VLAN).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'vlan_pcp',
        new VLAN.mkPcpMatch('0x00','0x00')));

    match.push(
      new Match.Match(null,
        'vlan_vid',
        new VLAN.mkVidMatch(
          '0xffff',
          '0xffff')));

    expect(match.match(key)).toBe(false);

    key.vlan_vid = new VLAN.mkVid('0xffff');
    key.vlan_pcp = new VLAN.mkPcp('0x00');

    expect(match.summarize().toString()).toBe('vlan');

    expect(match.match(key)).toBe(true);
  });

  it('IPv4 Match', function () {
    expect(!!Match).toBe(true);
    expect(!!IPV4).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'ipv4_dscp',
        new IPV4.mkDscpMatch('0x01','0xff')));

    expect(match.summarize().toString()).toBe('ipv4');

    match.push(
      new Match.Match(null,
        'ipv4_ecn',
        new IPV4.mkEcnMatch('0x02','0xff')));

    expect(match.summarize().toString()).toBe('ipv4');

    match.push(
      new Match.Match(null,
        'ipv4_proto',
        new IPV4.mkProtoMatch('0x03','0xff')));

    expect(match.summarize().toString()).toBe('ipv4');

    match.push(
      new Match.Match(null,
        'ipv4_src',
        new IPV4.mkAddressMatch('192.168.1.1','255.255.255.255')));

    match.push(
      new Match.Match(null,
        'ipv4_dst',
        new IPV4.mkAddressMatch('128.1.1.1','255.255.255.255')));

    expect(match.summarize().toString()).toBe('ipv4');
    expect(match.match(key)).toBe(false);

    key.ipv4_dscp = new IPV4.mkDscp('0x01');
    key.ipv4_ecn  = new IPV4.mkEcn('0x02');
    key.ipv4_proto = new IPV4.mkProto('0x03');
    key.ipv4_src = new IPV4.mkAddress('192.168.1.1');
    key.ipv4_dst = new IPV4.mkAddress('128.1.1.1');

    expect(match.summarize().toString()).toBe('ipv4');

    expect(match.match(key)).toBe(true);
  });

  it('MPLS Match', function () {
    expect(!!Match).toBe(true);
    expect(!!MPLS).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'mpls_label',
        new MPLS.mkLabelMatch('0x777777','0xffffff')));

    match.push(
      new Match.Match(null,
        'mpls_tc',
        new MPLS.mkTcMatch(
          '0x03',
          '0x03')));

    match.push(
      new Match.Match(null,
        'mpls_bos',
        new MPLS.mkBosMatch(
          '0x00',
          '0x00')));

    expect(match.match(key)).toBe(false);
    expect(match.summarize().toString()).toBe('mpls');
    key.mpls_label = new MPLS.mkLabel('0x777777');
    key.mpls_tc = new MPLS.mkTc('0x03');
    key.mpls_bos = new MPLS.mkBos('0xaa');

    expect(match.match(key)).toBe(true);
  });

  it('ARP Match', function () {
    expect(!!Match).toBe(true);
    expect(!!ARP).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'arp_opcode',
        new ARP.mkOpcodeMatch('0x0023','0xffff')));

    expect(match.summarize().toString()).toBe('arp');

    match.push(
      new Match.Match(null,
        'arp_sha',
        new ARP.mkShaMatch(
          '00:aa:bb:cc:dd:ee',
          'ff:ff:ff:ff:ff:ff')));

    expect(match.summarize().toString()).toBe('arp');

    match.push(
      new Match.Match(null,
        'arp_spa',
        new ARP.mkSpaMatch(
          '192.168.1.2',
          '255.255.255.255')));

    match.push(
      new Match.Match(null,
        'arp_tha',
        new ARP.mkThaMatch(
          '11:aa:bb:cc:dd:ee',
          'ff:ff:ff:ff:ff:ff')));

   match.push(
      new Match.Match(null,
        'arp_tpa',
        new ARP.mkTpaMatch(
          '192.168.1.100',
          '255.255.255.255')));

    expect(match.summarize().toString()).toBe('arp');
    expect(match.match(key)).toBe(false);

    key.arp_opcode = ARP.mkOpcode('0x0023');
    key.arp_sha    = ARP.mkSha('00:aa:bb:cc:dd:ee');
    key.arp_spa    = ARP.mkSpa('192.168.1.2');
    key.arp_tha    = ARP.mkTha('11:aa:bb:cc:dd:ee');
    key.arp_tpa    = ARP.mkTpa('192.168.1.100');

    expect(match.match(key)).toBe(true);

    key.arp_sha = ARP.mkSha('aa:bb:cc:dd:ee:ff');

    expect(match.match(key)).toBe(false);
  });

  it('UDP Match', function () {
    expect(!!Match).toBe(true);
    expect(!!UDP).toBe(true);

    var match = new Match.Set();
    match.push(
      new Match.Match(null,
        'udp_src',
        UDP.mkPortMatch(65535, '0xffff')));
    match.push(
      new Match.Match(null,
        'udp_dst',
        UDP.mkPortMatch(80, '0xffff')));

    var key = new Context.Key(null, 0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(2345);
    key.udp_dst = new UDP.mkPort(0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(65535);
    key.udp_dst = new UDP.mkPort(0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(2345);
    key.udp_dst = new UDP.mkPort(80);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(65535);
    key.udp_dst = new UDP.mkPort(80);
    expect(match.match(key)).toBe(true);

    var match = new Match.Set();
    match.push(
      new Match.Match(null,
        'udp_src',
        UDP.mkPortMatch(65535, '0x0')));
    match.push(
      new Match.Match(null,
        'udp_dst',
        UDP.mkPortMatch(80, '0xffff')));

    var key = new Context.Key(null, 0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(2345);
    key.udp_dst = new UDP.mkPort(0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(65535);
    key.udp_dst = new UDP.mkPort(0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(2345);
    key.udp_dst = new UDP.mkPort(80);
    expect(match.match(key)).toBe(true);

    key.udp_src = new UDP.mkPort(65535);
    key.udp_dst = new UDP.mkPort(80);
    expect(match.match(key)).toBe(true);

  });

  it('TCP Match', function () {
    expect(!!Match).toBe(true);
    expect(!!TCP).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'tcp_src',
        TCP.mkPortMatch(
          '22',
          '0xffff')));

    match.push(
      new Match.Match(null,
        'tcp_dst',
        TCP.mkPortMatch(
          '2222',
          '0xffff')));

    expect(match.match(key)).toBe(false);

    key.tcp_src = TCP.mkPort('22');
    key.tcp_dst = TCP.mkPort('2222');

    expect(match.match(key)).toBe(true);

    key.tcp_src = TCP.mkPort('65535');
    expect(match.match(key)).toBe(false);

    key.tcp_src = TCP.mkPort('22');
    key.tcp_dst = TCP.mkPort('65535');
    expect(match.match(key)).toBe(false);
  });

  it('IPV6 Match', function () {
    expect(!!Match).toBe(true);
    expect(!!IPV6).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'ipv6_flabel',
        IPV6.mkFlabelMatch(
          '22',
          '0xffff')));

    expect(match.summarize().toString()).toBe('ipv6');
    match.push(
      new Match.Match(null,
        'ipv6_src',
        IPV6.mkAddressMatch(
          '2001:0db8:0000:0000:0000:ff00:0042:8329',
          'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')));

    expect(match.summarize().toString()).toBe('ipv6');
    match.push(
      new Match.Match(null,
        'ipv6_dst',
        IPV6.mkAddressMatch(
          '2002:0db8:0000:0000:0000:ff00:0042:8329',
          'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')));

    expect(match.summarize().toString()).toBe('ipv6');
    expect(match.match(key)).toBe(false);

    key.ipv6_flabel = IPV6.mkFlabel('22');
    key.ipv6_src    = IPV6.mkAddress('2001:0db8:0000:0000:0000:ff00:0042:8329');
    key.ipv6_dst    = IPV6.mkAddress('2002:0db8:0000:0000:0000:ff00:0042:8329');

    expect(match.match(key)).toBe(true);

  });

  it('Match Summarize Pass', function () {
    expect(!!Match).toBe(true);
    expect(!!IPV6).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'ipv6_flabel',
        IPV6.mkFlabelMatch(
          '22',
          '0xffff')));

    expect(match.summarize().toString()).toBe('ipv6');
    match.push(
      new Match.Match(null,
        'mpls_label',
        MPLS.mkLabelMatch(
          '0x123456', '0xffffff')));

    expect(match.summarize().toString()).toBe('ipv6,mpls');
    match.push(
      new Match.Match(null,
        'ethernet_dst',
        ETHERNET.mkMACMatch(
          '00:bb:cc:aa:dd:ff', 'ff:ff:ff:ff:ff:ff')));

    expect(match.summarize().toString()).toBe('ipv6,mpls,eth');
    expect(match.match(key)).toBe(false);

  });
});
<commit_msg>match equal<commit_after>'use strict';

describe('Service: match', function () {

  // load the service's module
  beforeEach(module('flowsimUiApp'));

  // instantiate service
  var Match;
  beforeEach(inject(function (_Match_) {
    Match = _Match_;
  }));

  var UInt;
  beforeEach(inject(function (_UInt_) {
    UInt = _UInt_;
  }));

  var ETHERNET;
  beforeEach(inject(function (_ETHERNET_) {
    ETHERNET = _ETHERNET_;
  }));

  var VLAN;
  beforeEach(inject(function (_VLAN_) {
    VLAN = _VLAN_;
  }));

  var MPLS;
  beforeEach(inject(function (_MPLS_) {
    MPLS = _MPLS_;
  }));

  var ARP;
  beforeEach(inject(function (_ARP_) {
    ARP = _ARP_;
  }));

  var UDP;
  beforeEach(inject(function (_UDP_) {
    UDP = _UDP_;
  }));

  var TCP;
  beforeEach(inject(function (_TCP_) {
    TCP = _TCP_;
  }));

  var Context;
  beforeEach(inject(function(_Context_) {
    Context = _Context_;
  }));

  var IPV4;
  beforeEach(inject(function(_IPV4_) {
    IPV4 = _IPV4_;
  }));

  var IPV6;
  beforeEach(inject(function(_IPV6_) {
    IPV6 = _IPV6_;
  }));

  it('Default Match', function() {
    var key = new Context.Key(null, 0);
    var match = new Match.Set();
    expect(match.match(key)).toBe(true);
  });

  it('Match equality', function() {
    var match1 = new Match.Set();
    var match2 = new Match.Set();
    expect(match1.equal(match2)).toBe(true);
  });

  it('Ethernet Match', function () {
    expect(!!Match).toBe(true);
    expect(!!ETHERNET).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'eth_src',
        new ETHERNET.MAC.Match(
          null,
          '00:00:00:00:00:00',
          '00:00:00:00:00:00')));

    expect(match.summarize().toString()).toBe('eth');

    match.push(
      new Match.Match(null,
        'eth_dst',
        new ETHERNET.mkMACMatch(
          'ff:ff:ff:ff:ff:ff',
          'ff:ff:ff:ff:ff:ff')));

    expect(match.summarize().toString()).toBe('eth');

    match.push(
      new Match.Match(null,
        'eth_type',
        new ETHERNET.mkTypeMatch('0x0800', '0xffff')));

    expect(match.summarize().toString()).toBe('eth');

    expect(match.match(key)).toBe(false);

    key.eth_src = new ETHERNET.mkMAC('00:00:00:00:00:00');
    key.eth_dst = new ETHERNET.mkMAC('ff:ff:ff:ff:ff:ff');
    key.eth_type = new ETHERNET.mkType(0x0800);

    expect(match.match(key)).toBe(true);

    key.eth_src = new ETHERNET.mkMAC('00:00:00:00:00:01');
    expect(match.match(key)).toBe(true);

    key.eth_type = new ETHERNET.mkType('0x0806');
    expect(match.match(key)).toBe(false);

  });

  it('VLAN Match', function () {
    expect(!!Match).toBe(true);
    expect(!!VLAN).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'vlan_pcp',
        new VLAN.mkPcpMatch('0x00','0x00')));

    match.push(
      new Match.Match(null,
        'vlan_vid',
        new VLAN.mkVidMatch(
          '0xffff',
          '0xffff')));

    expect(match.match(key)).toBe(false);

    key.vlan_vid = new VLAN.mkVid('0xffff');
    key.vlan_pcp = new VLAN.mkPcp('0x00');

    expect(match.summarize().toString()).toBe('vlan');

    expect(match.match(key)).toBe(true);
  });

  it('IPv4 Match', function () {
    expect(!!Match).toBe(true);
    expect(!!IPV4).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'ipv4_dscp',
        new IPV4.mkDscpMatch('0x01','0xff')));

    expect(match.summarize().toString()).toBe('ipv4');

    match.push(
      new Match.Match(null,
        'ipv4_ecn',
        new IPV4.mkEcnMatch('0x02','0xff')));

    expect(match.summarize().toString()).toBe('ipv4');

    match.push(
      new Match.Match(null,
        'ipv4_proto',
        new IPV4.mkProtoMatch('0x03','0xff')));

    expect(match.summarize().toString()).toBe('ipv4');

    match.push(
      new Match.Match(null,
        'ipv4_src',
        new IPV4.mkAddressMatch('192.168.1.1','255.255.255.255')));

    match.push(
      new Match.Match(null,
        'ipv4_dst',
        new IPV4.mkAddressMatch('128.1.1.1','255.255.255.255')));

    expect(match.summarize().toString()).toBe('ipv4');
    expect(match.match(key)).toBe(false);

    key.ipv4_dscp = new IPV4.mkDscp('0x01');
    key.ipv4_ecn  = new IPV4.mkEcn('0x02');
    key.ipv4_proto = new IPV4.mkProto('0x03');
    key.ipv4_src = new IPV4.mkAddress('192.168.1.1');
    key.ipv4_dst = new IPV4.mkAddress('128.1.1.1');

    expect(match.summarize().toString()).toBe('ipv4');

    expect(match.match(key)).toBe(true);
  });

  it('MPLS Match', function () {
    expect(!!Match).toBe(true);
    expect(!!MPLS).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'mpls_label',
        new MPLS.mkLabelMatch('0x777777','0xffffff')));

    match.push(
      new Match.Match(null,
        'mpls_tc',
        new MPLS.mkTcMatch(
          '0x03',
          '0x03')));

    match.push(
      new Match.Match(null,
        'mpls_bos',
        new MPLS.mkBosMatch(
          '0x00',
          '0x00')));

    expect(match.match(key)).toBe(false);
    expect(match.summarize().toString()).toBe('mpls');
    key.mpls_label = new MPLS.mkLabel('0x777777');
    key.mpls_tc = new MPLS.mkTc('0x03');
    key.mpls_bos = new MPLS.mkBos('0xaa');

    expect(match.match(key)).toBe(true);
  });

  it('ARP Match', function () {
    expect(!!Match).toBe(true);
    expect(!!ARP).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'arp_opcode',
        new ARP.mkOpcodeMatch('0x0023','0xffff')));

    expect(match.summarize().toString()).toBe('arp');

    match.push(
      new Match.Match(null,
        'arp_sha',
        new ARP.mkShaMatch(
          '00:aa:bb:cc:dd:ee',
          'ff:ff:ff:ff:ff:ff')));

    expect(match.summarize().toString()).toBe('arp');

    match.push(
      new Match.Match(null,
        'arp_spa',
        new ARP.mkSpaMatch(
          '192.168.1.2',
          '255.255.255.255')));

    match.push(
      new Match.Match(null,
        'arp_tha',
        new ARP.mkThaMatch(
          '11:aa:bb:cc:dd:ee',
          'ff:ff:ff:ff:ff:ff')));

   match.push(
      new Match.Match(null,
        'arp_tpa',
        new ARP.mkTpaMatch(
          '192.168.1.100',
          '255.255.255.255')));

    expect(match.summarize().toString()).toBe('arp');
    expect(match.match(key)).toBe(false);

    key.arp_opcode = ARP.mkOpcode('0x0023');
    key.arp_sha    = ARP.mkSha('00:aa:bb:cc:dd:ee');
    key.arp_spa    = ARP.mkSpa('192.168.1.2');
    key.arp_tha    = ARP.mkTha('11:aa:bb:cc:dd:ee');
    key.arp_tpa    = ARP.mkTpa('192.168.1.100');

    expect(match.match(key)).toBe(true);

    key.arp_sha = ARP.mkSha('aa:bb:cc:dd:ee:ff');

    expect(match.match(key)).toBe(false);
  });

  it('UDP Match', function () {
    expect(!!Match).toBe(true);
    expect(!!UDP).toBe(true);

    var match = new Match.Set();
    match.push(
      new Match.Match(null,
        'udp_src',
        UDP.mkPortMatch(65535, '0xffff')));
    match.push(
      new Match.Match(null,
        'udp_dst',
        UDP.mkPortMatch(80, '0xffff')));

    var key = new Context.Key(null, 0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(2345);
    key.udp_dst = new UDP.mkPort(0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(65535);
    key.udp_dst = new UDP.mkPort(0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(2345);
    key.udp_dst = new UDP.mkPort(80);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(65535);
    key.udp_dst = new UDP.mkPort(80);
    expect(match.match(key)).toBe(true);

    var match = new Match.Set();
    match.push(
      new Match.Match(null,
        'udp_src',
        UDP.mkPortMatch(65535, '0x0')));
    match.push(
      new Match.Match(null,
        'udp_dst',
        UDP.mkPortMatch(80, '0xffff')));

    var key = new Context.Key(null, 0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(2345);
    key.udp_dst = new UDP.mkPort(0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(65535);
    key.udp_dst = new UDP.mkPort(0);
    expect(match.match(key)).toBe(false);

    key.udp_src = new UDP.mkPort(2345);
    key.udp_dst = new UDP.mkPort(80);
    expect(match.match(key)).toBe(true);

    key.udp_src = new UDP.mkPort(65535);
    key.udp_dst = new UDP.mkPort(80);
    expect(match.match(key)).toBe(true);

  });

  it('TCP Match', function () {
    expect(!!Match).toBe(true);
    expect(!!TCP).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'tcp_src',
        TCP.mkPortMatch(
          '22',
          '0xffff')));

    match.push(
      new Match.Match(null,
        'tcp_dst',
        TCP.mkPortMatch(
          '2222',
          '0xffff')));

    expect(match.match(key)).toBe(false);

    key.tcp_src = TCP.mkPort('22');
    key.tcp_dst = TCP.mkPort('2222');

    expect(match.match(key)).toBe(true);

    key.tcp_src = TCP.mkPort('65535');
    expect(match.match(key)).toBe(false);

    key.tcp_src = TCP.mkPort('22');
    key.tcp_dst = TCP.mkPort('65535');
    expect(match.match(key)).toBe(false);
  });

  it('IPV6 Match', function () {
    expect(!!Match).toBe(true);
    expect(!!IPV6).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    match.push(
      new Match.Match(null,
        'ipv6_flabel',
        IPV6.mkFlabelMatch(
          '22',
          '0xffff')));

    expect(match.summarize().toString()).toBe('ipv6');
    match.push(
      new Match.Match(null,
        'ipv6_src',
        IPV6.mkAddressMatch(
          '2001:0db8:0000:0000:0000:ff00:0042:8329',
          'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')));

    expect(match.summarize().toString()).toBe('ipv6');
    match.push(
      new Match.Match(null,
        'ipv6_dst',
        IPV6.mkAddressMatch(
          '2002:0db8:0000:0000:0000:ff00:0042:8329',
          'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')));

    expect(match.summarize().toString()).toBe('ipv6');
    expect(match.match(key)).toBe(false);

    key.ipv6_flabel = IPV6.mkFlabel('22');
    key.ipv6_src    = IPV6.mkAddress('2001:0db8:0000:0000:0000:ff00:0042:8329');
    key.ipv6_dst    = IPV6.mkAddress('2002:0db8:0000:0000:0000:ff00:0042:8329');

    expect(match.match(key)).toBe(true);

  });

  it('Match Summarize Pass', function () {
    expect(!!Match).toBe(true);
    expect(!!IPV6).toBe(true);

    var match = new Match.Set();

    var key = new Context.Key(null, 0);

    expect(match.summarize().toString()).toBe('*');
    match.push(
      new Match.Match(null,
        'ipv6_flabel',
        IPV6.mkFlabelMatch(
          '22',
          '0xffff')));

    expect(match.summarize().toString()).toBe('ipv6');
    match.push(
      new Match.Match(null,
        'mpls_label',
        MPLS.mkLabelMatch(
          '0x123456', '0xffffff')));

    expect(match.summarize().toString()).toBe('ipv6,mpls');
    match.push(
      new Match.Match(null,
        'ethernet_dst',
        ETHERNET.mkMACMatch(
          '00:bb:cc:aa:dd:ff', 'ff:ff:ff:ff:ff:ff')));

    expect(match.summarize().toString()).toBe('ipv6,mpls,eth');
    expect(match.match(key)).toBe(false);

  });
});
<|endoftext|>


<commit_before>'use strict';

angular.module('myApp.view1', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/', {
            templateUrl: 'view1/view1.html',
            controller:  'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', '$timeout', '$interval', function ($scope, $timeout, $interval) {
        function stackTrace(msg) {
            var err = new Error(msg);
            throw err.stack;
        }

        var simon = {
            states:          {
                on:        function () {
                    /* state: on */
                    this.view.gameOn    = true;
                    this.view.counterOn = true;
                    // next state
                    this._addEvent(0, this, this._setState, this.states.ready);
                    console.log('state on ran');
                },
                off:       function () {
                    /* state: off */
                    this.view.gameOn    = false;
                    this.view.strict    = false;
                    this.view.counter   = '- -';
                    this.view.counterOn = false;

                    // clean up
                    this._cleanup();

                    // set state to undefined - this is our initial state
                    this._addEvent(0, this, this._setState, undefined);
                    // stop heartbeat 100ms latter - this gives update time to process any clean up events
                    this._addEvent(100, this, this._stopHeartBeat, undefined);
                },
                ready:     function () {
                    /* state: ready */
                },
                run:       function () {
                    /* state: run */
                },
                waiting:   function () {
                    /* state: waiting */
                },
                animating: function () {
                    /* state: animating */
                    // empty marker state
                },
                playing:   function () {
                    /* state: playing */
                },
                start:     function () {
                    /* state: start */

                    // clean up
                    this._cleanup();

                    // generate a sequence
                    this._generateSequence();

                    // set start to restart - this was done to avoid code duplication as
                    // restart already dose what needed to be done to start
                    var parent = this;
                    this.failTimerID = this._addEvent(0, this, this._setState, parent.states.restart);
                },
                restart:   function () {
                    /* state: restart */
                    this.seqNum = 0;

                    // play sequence
                    var delay = this._playSequence();

                    // set state to run
                    var parent = this;
                    this._addEvent(delay, this, this._setState, parent.states.run);

                    // add event to time out if they take too long to input buttons
                    // keep event id so we can cancel it
                    this.failTimerID = this._addEvent(delay + this.inputTimeOut, this, this._setState, parent.states.failed);
                },
                failed:    function () {
                    /* state: failed */

                    // cancel any fail timer - this way it doesnt get called twice
                    if (this.failTimerID !== undefined) {
                        this._removeEvent(this.failTimerID);
                        this.failTimerID = undefined;
                    }

                    console.log('failed');
                    // player failed for some reason, we don't care why

                    var nextState = this.states.restart;
                    // if strict that's it game over / restart
                    if (this.strict) {
                        nextState = this.states.start;
                    }

                    // play animation.error
                    this.animation.play(this, this.animation.error, nextState);
                }
            }, /* end of states */
            animation:       {
                play:  function (scope, animation, nextState) {
                    scope._addEvent(0, scope, scope._setState, scope.states.animating);
                    var animationTime = animation(scope);
                    scope._addEvent(animationTime, scope, scope._setState, nextState);
                },
                error: function (scope) {
                    var flashTime = 300;
                    var time = 0;

                    scope.view.counter    = '! !';
                    var flashFunc = function () {
                        scope.view.counterOn = !scope.view.counterOn;
                    };

                    // tell view to flash ! !
                    for (var i = 1; i < 6; i++) {
                        scope._addEvent(time, scope, flashFunc);
                        time += flashTime;
                    }
                    return time;
                }

            }, /* end of animation */
            _startHeartBeat: function () {
                // heart beat
                var parent     = this;
                var lastTick   = Date.now();
                var updateTick = function () {
                    var tick = Date.now();
                    parent._onUpdate(tick - lastTick);
                    lastTick = tick;
                };
                this.heartBeat = $interval(updateTick, 33, 0, true);
            },
            _stopHeartBeat:  function () {
                $interval.cancel(this.heartBeat);
                this.heartBeat = undefined;
            },
            _setCallback:    function (callback) {
                if (callback === undefined) {
                    stackTrace('callback undefined!');
                }
                this.callback = callback;
            },
            on:              function (callback) {
                if (callback === undefined) {
                    stackTrace('callback cannot be undefined!');
                }
                this._setCallback(callback);
                this._startHeartBeat();
                var parent = this;
                this._addEvent(0, this, this._setState, parent.states.on);
            },
            off:             function () {
                var parent = this;
                this._addEvent(0, this, this._setState, parent.states.off);
            },
            toggleStrict:    function () {
                this.view.strictOn = !this.view.strictOn;
            },
            _onUpdate:       function (dt) {
                this._processEvents(dt);

                // testing
                //console.log(this.state);
                if (this.state !== undefined) {
                    this.state();
                }
                /*if (this.state === this.states.off) {
                    //this.state();
                }*/

                // tell view to update
                this.callback();
                //$scope.$apply();
            },
            _addEvent:       function (delay, scope, func, prams) {
                var id = this.events.length;
                this.events.push({id: id, scope: scope, delay: delay, func: func, prams: prams});
                return id;
            },
            _removeEvent:    function (id) {
                this.events.some(function (element, index) {
                    if (element.id === id) {
                        this.events[index] = undefined;
                        return true;
                    }
                }, this);
            },
            _removeAllEvents: function () {
                this.events = [];
            },
            _processEvents:  function (dt) {
                var marker = 'marker';
                this.events.push(marker);

                var shifted;
                do {
                    shifted = this.events.shift();
                    if (shifted !== marker && shifted !== undefined) {
                        shifted.delay -= dt;
                        if (shifted.delay <= 0) {
                            shifted.func.bind(shifted.scope)(shifted.prams);
                        } else {
                            this.events.push(shifted);
                        }
                    }
                } while (shifted !== marker);
            },
            _cleanup:        function () {
                // clear all events
                this._removeAllEvents();

                // reset view and other data
                this.view.counter   = '- -';
                this.seqCount       = 0;
                this.seqNum         = 0;
                this.view.btnGreen  = false;
                this.view.btnRed    = false;
                this.view.btnBlue   = false;
                this.view.btnYellow = false;
                this.view.sndToPlay = undefined;
            },

            start:             function () {
                if (!this.view.gameOn) {
                    return;
                }
                console.log('starting');

                // set state to start
                var parent = this;
                this._addEvent(0, this, this._setState, parent.states.start);
            },
            _setState:         function (newState) {
                this.state = newState;
            },
            btnInput:          function (color) {
                if (this.state !== this.states.run) {
                    return;
                }
                var btn;
                var btnNum;
                if (color === 'green') {
                    btn    = 'btnGreen';
                    btnNum = 1;
                } else if (color === 'red') {
                    btn    = 'btnRed';
                    btnNum = 2;
                } else if (color === 'blue') {
                    btn    = 'btnBlue';
                    btnNum = 3;
                } else if (color === 'yellow') {
                    btn    = 'btnYellow';
                    btnNum = 4;
                }

                // play sound and light button
                this._addEvent(0, this, this._btnOn, btn);
                this._addEvent(this.btnFlashTime, this, this._btnOff, btn);

                // process input
                // good input
                var parent = this;
                if (this.sequence[this.seqNum] === btnNum) {
                    this.seqNum++;

                    if (this.seqNum > this.seqCount) {
                        console.log('this.seqNum > this.seqCount');
                        this.seqNum = 0;
                        this.seqCount++;

                        // cancel fail timer
                        this._removeEvent(this.failTimerID);

                        // play sequence
                        var delay = this._playSequence();

                        // set state to run
                        this._addEvent(delay, this, this._setState, parent.states.run);

                        // add event to time out if they take too long to input buttons
                        // keep event id so we can cancel it
                        this.failTimerID = this._addEvent(delay + this.inputTimeOut, this, this._setState, parent.states.failed);
                    }
                } else {
                    // bad input - set state to failed
                    this._addEvent(0, this, this._setState, parent.states.failed);
                }
            },
            _generateSequence: function () {
                this.sequence = [];
                for (var i = 0; i < 20; i++) {
                    var num = Math.floor(Math.random() * (5 - 1)) + 1;
                    this.sequence.push(num);
                }
            },
            // todo turn playSequence into an animation
            _playSequence:     function () {
                console.log('_playSequence');

                var delay = this.timeDelay;
                // set state to playing to prevent user actions other than on/off
                var parent = this;
                this._addEvent(0, this, this._setState, parent.states.animating);

                for (var i = 0; i < this.seqCount + 1; i++) {
                    // button on
                    this._addEvent(delay, this, this._btnOn, this._getBtn(this.sequence[i]));
                    // button off
                    this._addEvent(delay + this.btnFlashTime, this, this._btnOff, this._getBtn(this.sequence[i]));
                    delay += this.timeDelay;
                }
                return delay;
            },
            _btnOn:            function (btn) {
                this.view[btn]      = true;
                this.view.sndToPlay = this.view[btn + 'Snd'];
            },
            _btnOff:           function (btn) {
                this.view[btn]      = false;
                this.view.sndToPlay = undefined;
            },
            _getBtn:           function (nbr) {
                switch (nbr) {
                    case 1:
                        return 'btnGreen';
                    case 2:
                        return 'btnRed';
                    case 3:
                        return 'btnBlue';
                    case 4:
                        return 'btnYellow';
                }
            },
            getSoundToPlay:  function () {
                var result          = this.view.sndToPlay;
                this.view.sndToPlay = undefined;
                return result;
            },
            view:            {
                btnGreen:  false,
                btnRed:    false,
                btnBlue:   false,
                btnYellow: false,
                sndToPlay: undefined,
                counter:   '- -',
                counterOn: false,
                strictOn:  false,
                gameOn:    false
            },
            sounds:          {
                btnGreenSnd:  'assets/sounds/simonSound1.mp3',
                btnRedSnd:    'assets/sounds/simonSound2.mp3',
                btnBlueSnd:   'assets/sounds/simonSound3.mp3',
                btnYellowSnd: 'assets/sounds/simonSound4.mp3',
            },
            events:          [],
            state:           undefined,
            sequence:        [],
            seqCount:        0,                 // end of the current rnd
            seqNum:          0,                 // how many correct buttons player has pushed
            promises:        [],
            timeDelay:       1250,              // millisecond time delay between buttons
            btnFlashTime:    750,               // millisecond how long to leave a button on.
            inputTimeOut:    8000,              // time player has to input the correct sequence
            autoRestartTime: 2000,              // millisecond how long to wait before restart
            flashTime:       300,
            failTimerID:     undefined,
            heartBeat:       undefined
        };
        /* end of simon */

        var onOffSwitch    = false;
        var updateView     = function () {
            $scope.onOff       = simon.view.gameOn;
            $scope.counterOn   = simon.view.counterOn;
            $scope.strictLed   = simon.view.strictOn;
            $scope.count       = simon.view.counter;
            $scope.greenBtnOn  = simon.view.btnGreen;
            $scope.redBtnOn    = simon.view.btnRed;
            $scope.blueBtnOn   = simon.view.btnBlue;
            $scope.yellowBtnOn = simon.view.btnYellow;

            var sndToPlay = simon.getSoundToPlay();
            if (sndToPlay !== undefined) {
                var audio = new Audio(sndToPlay);
                audio.play();
            }
            //$scope.$apply();
        };
        $scope.switchClick = function () {
            onOffSwitch = !onOffSwitch;
            if (onOffSwitch) {
                simon.on(updateView);
            } else {
                simon.off();
            }
        };
        $scope.strictClick = function () {
            simon.toggleStrict();
        };
        $scope.btnPress    = function (color) {
            simon.btnInput(color);
        };
        $scope.startBtn    = function () {
            simon.start();
        };
        updateView();

        /*
         simon.toggleOnOff();
         simon._generateSequence();
         simon.seqCount = 19;
         simon._playSequence('testing');
         */

    }])
;<commit_msg>updated run state to set view.counter<commit_after>'use strict';

angular.module('myApp.view1', ['ngRoute'])

    .config(['$routeProvider', function ($routeProvider) {
        $routeProvider.when('/', {
            templateUrl: 'view1/view1.html',
            controller:  'View1Ctrl'
        });
    }])

    .controller('View1Ctrl', ['$scope', '$timeout', '$interval', function ($scope, $timeout, $interval) {
        function stackTrace(msg) {
            var err = new Error(msg);
            throw err.stack;
        }

        var simon = {
            states:          {
                on:        function () {
                    /* state: on */
                    this.view.gameOn    = true;
                    this.view.counterOn = true;
                    // next state
                    this._addEvent(0, this, this._setState, this.states.ready);
                    console.log('state on ran');
                },
                off:       function () {
                    /* state: off */
                    this.view.gameOn    = false;
                    this.view.strict    = false;
                    this.view.counter   = '- -';
                    this.view.counterOn = false;

                    // clean up
                    this._cleanup();

                    // set state to undefined - this is our initial state
                    this._addEvent(0, this, this._setState, undefined);
                    // stop heartbeat 100ms latter - this gives update time to process any clean up events
                    this._addEvent(100, this, this._stopHeartBeat, undefined);
                },
                ready:     function () {
                    /* state: ready */
                },
                run:       function () {
                    /* state: run */
                    this.view.counter = this.seqCount + 1;
                },
                waiting:   function () {
                    /* state: waiting */
                },
                animating: function () {
                    /* state: animating */
                    // empty marker state
                },
                playing:   function () {
                    /* state: playing */
                },
                start:     function () {
                    /* state: start */

                    // clean up
                    this._cleanup();

                    // generate a sequence
                    this._generateSequence();

                    // set start to restart - this was done to avoid code duplication as
                    // restart already dose what needed to be done to start
                    var parent = this;
                    this.failTimerID = this._addEvent(0, this, this._setState, parent.states.restart);
                },
                restart:   function () {
                    /* state: restart */
                    this.seqNum = 0;

                    // play sequence
                    var delay = this._playSequence();

                    // set state to run
                    var parent = this;
                    this._addEvent(delay, this, this._setState, parent.states.run);

                    // add event to time out if they take too long to input buttons
                    // keep event id so we can cancel it
                    this.failTimerID = this._addEvent(delay + this.inputTimeOut, this, this._setState, parent.states.failed);
                },
                failed:    function () {
                    /* state: failed */

                    // cancel any fail timer - this way it doesnt get called twice
                    if (this.failTimerID !== undefined) {
                        this._removeEvent(this.failTimerID);
                        this.failTimerID = undefined;
                    }

                    console.log('failed');
                    // player failed for some reason, we don't care why

                    var nextState = this.states.restart;
                    // if strict that's it game over / restart
                    if (this.strict) {
                        nextState = this.states.start;
                    }

                    // play animation.error
                    this.animation.play(this, this.animation.error, nextState);
                }
            }, /* end of states */
            animation:       {
                play:  function (scope, animation, nextState) {
                    scope._addEvent(0, scope, scope._setState, scope.states.animating);
                    var animationTime = animation(scope);
                    scope._addEvent(animationTime, scope, scope._setState, nextState);
                },
                error: function (scope) {
                    var flashTime = 300;
                    var time = 0;

                    scope.view.counter    = '! !';
                    var flashFunc = function () {
                        scope.view.counterOn = !scope.view.counterOn;
                    };

                    // tell view to flash ! !
                    for (var i = 1; i < 6; i++) {
                        scope._addEvent(time, scope, flashFunc);
                        time += flashTime;
                    }
                    return time;
                }

            }, /* end of animation */
            _startHeartBeat: function () {
                // heart beat
                var parent     = this;
                var lastTick   = Date.now();
                var updateTick = function () {
                    var tick = Date.now();
                    parent._onUpdate(tick - lastTick);
                    lastTick = tick;
                };
                this.heartBeat = $interval(updateTick, 33, 0, true);
            },
            _stopHeartBeat:  function () {
                $interval.cancel(this.heartBeat);
                this.heartBeat = undefined;
            },
            _setCallback:    function (callback) {
                if (callback === undefined) {
                    stackTrace('callback undefined!');
                }
                this.callback = callback;
            },
            on:              function (callback) {
                if (callback === undefined) {
                    stackTrace('callback cannot be undefined!');
                }
                this._setCallback(callback);
                this._startHeartBeat();
                var parent = this;
                this._addEvent(0, this, this._setState, parent.states.on);
            },
            off:             function () {
                var parent = this;
                this._addEvent(0, this, this._setState, parent.states.off);
            },
            toggleStrict:    function () {
                this.view.strictOn = !this.view.strictOn;
            },
            _onUpdate:       function (dt) {
                this._processEvents(dt);

                // testing
                //console.log(this.state);
                if (this.state !== undefined) {
                    this.state();
                }
                /*if (this.state === this.states.off) {
                    //this.state();
                }*/

                // tell view to update
                this.callback();
                //$scope.$apply();
            },
            _addEvent:       function (delay, scope, func, prams) {
                var id = this.events.length;
                this.events.push({id: id, scope: scope, delay: delay, func: func, prams: prams});
                return id;
            },
            _removeEvent:    function (id) {
                this.events.some(function (element, index) {
                    if (element.id === id) {
                        this.events[index] = undefined;
                        return true;
                    }
                }, this);
            },
            _removeAllEvents: function () {
                this.events = [];
            },
            _processEvents:  function (dt) {
                var marker = 'marker';
                this.events.push(marker);

                var shifted;
                do {
                    shifted = this.events.shift();
                    if (shifted !== marker && shifted !== undefined) {
                        shifted.delay -= dt;
                        if (shifted.delay <= 0) {
                            shifted.func.bind(shifted.scope)(shifted.prams);
                        } else {
                            this.events.push(shifted);
                        }
                    }
                } while (shifted !== marker);
            },
            _cleanup:        function () {
                // clear all events
                this._removeAllEvents();

                // reset view and other data
                this.view.counter   = '- -';
                this.seqCount       = 0;
                this.seqNum         = 0;
                this.view.btnGreen  = false;
                this.view.btnRed    = false;
                this.view.btnBlue   = false;
                this.view.btnYellow = false;
                this.view.sndToPlay = undefined;
            },

            start:             function () {
                if (!this.view.gameOn) {
                    return;
                }
                console.log('starting');

                // set state to start
                var parent = this;
                this._addEvent(0, this, this._setState, parent.states.start);
            },
            _setState:         function (newState) {
                this.state = newState;
            },
            btnInput:          function (color) {
                if (this.state !== this.states.run) {
                    return;
                }
                var btn;
                var btnNum;
                if (color === 'green') {
                    btn    = 'btnGreen';
                    btnNum = 1;
                } else if (color === 'red') {
                    btn    = 'btnRed';
                    btnNum = 2;
                } else if (color === 'blue') {
                    btn    = 'btnBlue';
                    btnNum = 3;
                } else if (color === 'yellow') {
                    btn    = 'btnYellow';
                    btnNum = 4;
                }

                // play sound and light button
                this._addEvent(0, this, this._btnOn, btn);
                this._addEvent(this.btnFlashTime, this, this._btnOff, btn);

                // process input
                // good input
                var parent = this;
                if (this.sequence[this.seqNum] === btnNum) {
                    this.seqNum++;

                    if (this.seqNum > this.seqCount) {
                        console.log('this.seqNum > this.seqCount');
                        this.seqNum = 0;
                        this.seqCount++;

                        // cancel fail timer
                        this._removeEvent(this.failTimerID);

                        // play sequence
                        var delay = this._playSequence();

                        // set state to run
                        this._addEvent(delay, this, this._setState, parent.states.run);

                        // add event to time out if they take too long to input buttons
                        // keep event id so we can cancel it
                        this.failTimerID = this._addEvent(delay + this.inputTimeOut, this, this._setState, parent.states.failed);
                    }
                } else {
                    // bad input - set state to failed
                    this._addEvent(0, this, this._setState, parent.states.failed);
                }
            },
            _generateSequence: function () {
                this.sequence = [];
                for (var i = 0; i < 20; i++) {
                    var num = Math.floor(Math.random() * (5 - 1)) + 1;
                    this.sequence.push(num);
                }
            },
            // todo turn playSequence into an animation
            _playSequence:     function () {
                console.log('_playSequence');

                var delay = this.timeDelay;
                // set state to playing to prevent user actions other than on/off
                var parent = this;
                this._addEvent(0, this, this._setState, parent.states.animating);

                for (var i = 0; i < this.seqCount + 1; i++) {
                    // button on
                    this._addEvent(delay, this, this._btnOn, this._getBtn(this.sequence[i]));
                    // button off
                    this._addEvent(delay + this.btnFlashTime, this, this._btnOff, this._getBtn(this.sequence[i]));
                    delay += this.timeDelay;
                }
                return delay;
            },
            _btnOn:            function (btn) {
                this.view[btn]      = true;
                this.view.sndToPlay = this.view[btn + 'Snd'];
            },
            _btnOff:           function (btn) {
                this.view[btn]      = false;
                this.view.sndToPlay = undefined;
            },
            _getBtn:           function (nbr) {
                switch (nbr) {
                    case 1:
                        return 'btnGreen';
                    case 2:
                        return 'btnRed';
                    case 3:
                        return 'btnBlue';
                    case 4:
                        return 'btnYellow';
                }
            },
            getSoundToPlay:  function () {
                var result          = this.view.sndToPlay;
                this.view.sndToPlay = undefined;
                return result;
            },
            view:            {
                btnGreen:  false,
                btnRed:    false,
                btnBlue:   false,
                btnYellow: false,
                sndToPlay: undefined,
                counter:   '- -',
                counterOn: false,
                strictOn:  false,
                gameOn:    false
            },
            sounds:          {
                btnGreenSnd:  'assets/sounds/simonSound1.mp3',
                btnRedSnd:    'assets/sounds/simonSound2.mp3',
                btnBlueSnd:   'assets/sounds/simonSound3.mp3',
                btnYellowSnd: 'assets/sounds/simonSound4.mp3',
            },
            events:          [],
            state:           undefined,
            sequence:        [],
            seqCount:        0,                 // end of the current rnd
            seqNum:          0,                 // how many correct buttons player has pushed
            promises:        [],
            timeDelay:       1250,              // millisecond time delay between buttons
            btnFlashTime:    750,               // millisecond how long to leave a button on.
            inputTimeOut:    8000,              // time player has to input the correct sequence
            autoRestartTime: 2000,              // millisecond how long to wait before restart
            flashTime:       300,
            failTimerID:     undefined,
            heartBeat:       undefined
        };
        /* end of simon */

        var onOffSwitch    = false;
        var updateView     = function () {
            $scope.onOff       = simon.view.gameOn;
            $scope.counterOn   = simon.view.counterOn;
            $scope.strictLed   = simon.view.strictOn;
            $scope.count       = simon.view.counter;
            $scope.greenBtnOn  = simon.view.btnGreen;
            $scope.redBtnOn    = simon.view.btnRed;
            $scope.blueBtnOn   = simon.view.btnBlue;
            $scope.yellowBtnOn = simon.view.btnYellow;

            var sndToPlay = simon.getSoundToPlay();
            if (sndToPlay !== undefined) {
                var audio = new Audio(sndToPlay);
                audio.play();
            }
            //$scope.$apply();
        };
        $scope.switchClick = function () {
            onOffSwitch = !onOffSwitch;
            if (onOffSwitch) {
                simon.on(updateView);
            } else {
                simon.off();
            }
        };
        $scope.strictClick = function () {
            simon.toggleStrict();
        };
        $scope.btnPress    = function (color) {
            simon.btnInput(color);
        };
        $scope.startBtn    = function () {
            simon.start();
        };
        updateView();

        /*
         simon.toggleOnOff();
         simon._generateSequence();
         simon.seqCount = 19;
         simon._playSequence('testing');
         */

    }])
;<|endoftext|>


<commit_before>import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';

import CodeMirror from 'react-codemirror';
import CM from 'codemirror';

import Rx from 'rxjs/Rx';

import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/hint/anyword-hint';
import 'codemirror/addon/search/search';
import 'codemirror/addon/search/searchcursor';

// matching & closing parentheses and quotations
import 'codemirror/addon/edit/matchbrackets';
import 'codemirror/addon/edit/closebrackets';

import 'codemirror/addon/dialog/dialog';

import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css';
import 'codemirror/mode/julia/julia';
import 'codemirror/mode/r/r';
import 'codemirror/mode/markdown/markdown';

import './codemirror-ipython';

import { codeComplete, pick, formChangeObject } from './complete';

import { updateCellSource } from '../../../actions';

function goLineUpOrEmit(editor) {
  const cursor = editor.getCursor();
  if (cursor.line === 0 && cursor.ch === 0 && !editor.somethingSelected()) {
    CM.signal(editor, 'topBoundary');
  } else {
    editor.execCommand('goLineUp');
  }
}

function goLineDownOrEmit(editor) {
  const cursor = editor.getCursor();
  const lastLineNumber = editor.lastLine();
  const lastLine = editor.getLine(lastLineNumber);
  if (cursor.line === lastLineNumber &&
      cursor.ch === lastLine.length &&
      !editor.somethingSelected()) {
    CM.signal(editor, 'bottomBoundary');
  } else {
    editor.execCommand('goLineDown');
  }
}

const excludedIntelliSenseTriggerKeys = {
  8: 'backspace',
  9: 'tab',
  13: 'enter',
  16: 'shift',
  17: 'ctrl',
  18: 'alt',
  19: 'pause',
  20: 'capslock',
  27: 'escape',
  32: 'space',
  33: 'pageup',
  34: 'pagedown',
  35: 'end',
  36: 'home',
  37: 'left',
  38: 'up',
  39: 'right',
  40: 'down',
  45: 'insert',
  46: 'delete',
  91: 'left window key',
  92: 'right window key',
  93: 'select',
  107: 'add',
  109: 'subtract',
  110: 'decimal point',
  111: 'divide',
  112: 'f1',
  113: 'f2',
  114: 'f3',
  115: 'f4',
  116: 'f5',
  117: 'f6',
  118: 'f7',
  119: 'f8',
  120: 'f9',
  121: 'f10',
  122: 'f11',
  123: 'f12',
  144: 'numlock',
  145: 'scrolllock',
  186: 'semicolon',
  187: 'equalsign',
  188: 'comma',
  189: 'dash',
  // 190: 'period',
  // 191: 'slash',
  192: 'graveaccent',
  220: 'backslash',
  222: 'quote',
};

CM.keyMap.basic.Up = 'goLineUpOrEmit';
CM.keyMap.basic.Down = 'goLineDownOrEmit';
CM.commands.goLineUpOrEmit = goLineUpOrEmit;
CM.commands.goLineDownOrEmit = goLineDownOrEmit;

export default class Editor extends React.Component {
  static propTypes = {
    autoCloseBrackets: React.PropTypes.bool,
    id: React.PropTypes.string,
    input: React.PropTypes.any,
    completion: React.PropTypes.bool,
    language: React.PropTypes.string,
    tabSize: React.PropTypes.number,
    lineNumbers: React.PropTypes.bool,
    lineWrapping: React.PropTypes.bool,
    onChange: React.PropTypes.func,
    matchBrackets: React.PropTypes.bool,
    theme: React.PropTypes.string,
    cmtheme: React.PropTypes.string,
    focused: React.PropTypes.bool,
    focusAbove: React.PropTypes.func,
    focusBelow: React.PropTypes.func,
  };

  static contextTypes = {
    store: React.PropTypes.object,
  };

  static defaultProps = {
    autoCloseBrackets: true, // automatically closes opening parens and quotations
    language: 'python',
    lineNumbers: false,
    matchBrackets: true, // highlights parens that are paired
    cmtheme: 'composition',
    focused: false,
  };

  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
    this.state = {
      source: this.props.input,
    };
    this.onChange = this.onChange.bind(this);

    this.hint = this.completions.bind(this);
    this.hint.async = true;

    // Remember the name of the theme that's applied so that when it changes we
    // can force codemirror to remeasure.
    this.theme = null;
  }

  componentDidMount() {
    // On first load, if focused, set codemirror to focus
    if (this.props.focused) {
      this.refs.codemirror.focus();
    }

    const cm = this.refs.codemirror.getCodeMirror();
    cm.on('topBoundary', this.props.focusAbove);
    cm.on('bottomBoundary', this.props.focusBelow);

    const keyupEvents = Rx.Observable.fromEvent(cm, 'keyup', (editor, ev) => ({ editor, ev }));

    keyupEvents
      .switchMap(i => Rx.Observable.of(i))
      .subscribe(({ editor, ev }) => {
        const cursor = editor.getDoc().getCursor();
        const token = editor.getTokenAt(cursor);

        if (!editor.state.completionActive &&
            !excludedIntelliSenseTriggerKeys[(ev.keyCode || ev.which).toString()] &&
            (token.type === 'tag' || token.type === 'variable' || token.string === ' ' ||
             token.string === '<' || token.string === '/') &&
            store.getState().app.executionState === 'idle') {
          editor.execCommand('autocomplete', { completeSingle: false });
        }
      });
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      source: nextProps.input,
    });
  }

  componentDidUpdate(prevProps) {
    if (this.props.focused && prevProps.focused !== this.props.focused) {
      this.refs.codemirror.focus();
    } else if (!this.props.focused && prevProps.focused !== this.props.focused) {
      const cm = this.refs.codemirror.getCodeMirror();
      cm.getInputField().blur();
    }

    if (this.theme !== this.props.theme) {
      this.theme = this.props.theme;
      this.refs.codemirror.getCodeMirror().refresh();
    }
  }

  onChange(text) {
    if (this.props.onChange) {
      this.props.onChange(text);
    } else {
      this.setState({
        source: text,
      });
      this.context.store.dispatch(updateCellSource(this.props.id, text));
    }
  }

  completions(editor, callback) {
    if (!this.props.completion) {
      return;
    }

    const state = this.context.store.getState();
    const channels = state.app.channels;

    codeComplete(channels, editor)
      .subscribe(callback);
  }

  render() {
    const options = {
      autoCloseBrackets: this.props.autoCloseBrackets,
      mode: this.props.language,
      lineNumbers: this.props.lineNumbers,
      lineWrapping: this.props.lineWrapping,
      matchBrackets: this.props.matchBrackets,
      theme: this.props.cmtheme,
      autofocus: false,
      hintOptions: {
        hint: this.hint,
        completeSingle: false, // In automatic autocomplete mode we don't want override
        extraKeys: {
          Right: pick,
        },
      },
      extraKeys: {
        'Ctrl-Space': 'autocomplete',
      },
      indentUnit: this.props.tabSize,
      tabSize: this.props.tabSize,
    };
    return (

        <CodeMirror
          value={this.state.source}
          ref="codemirror"
          className="cell_cm"
          options={options}
          onChange={this.onChange}
        />

    );
  }
}
<commit_msg>refactor(editor): use DOM refs instead of string refs<commit_after>import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin';

import CodeMirror from 'react-codemirror';
import CM from 'codemirror';

import Rx from 'rxjs/Rx';

import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/hint/anyword-hint';
import 'codemirror/addon/search/search';
import 'codemirror/addon/search/searchcursor';

// matching & closing parentheses and quotations
import 'codemirror/addon/edit/matchbrackets';
import 'codemirror/addon/edit/closebrackets';

import 'codemirror/addon/dialog/dialog';

import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/css/css';
import 'codemirror/mode/julia/julia';
import 'codemirror/mode/r/r';
import 'codemirror/mode/markdown/markdown';

import './codemirror-ipython';

import { codeComplete, pick, formChangeObject } from './complete';

import { updateCellSource } from '../../../actions';

function goLineUpOrEmit(editor) {
  const cursor = editor.getCursor();
  if (cursor.line === 0 && cursor.ch === 0 && !editor.somethingSelected()) {
    CM.signal(editor, 'topBoundary');
  } else {
    editor.execCommand('goLineUp');
  }
}

function goLineDownOrEmit(editor) {
  const cursor = editor.getCursor();
  const lastLineNumber = editor.lastLine();
  const lastLine = editor.getLine(lastLineNumber);
  if (cursor.line === lastLineNumber &&
      cursor.ch === lastLine.length &&
      !editor.somethingSelected()) {
    CM.signal(editor, 'bottomBoundary');
  } else {
    editor.execCommand('goLineDown');
  }
}

const excludedIntelliSenseTriggerKeys = {
  8: 'backspace',
  9: 'tab',
  13: 'enter',
  16: 'shift',
  17: 'ctrl',
  18: 'alt',
  19: 'pause',
  20: 'capslock',
  27: 'escape',
  32: 'space',
  33: 'pageup',
  34: 'pagedown',
  35: 'end',
  36: 'home',
  37: 'left',
  38: 'up',
  39: 'right',
  40: 'down',
  45: 'insert',
  46: 'delete',
  91: 'left window key',
  92: 'right window key',
  93: 'select',
  107: 'add',
  109: 'subtract',
  110: 'decimal point',
  111: 'divide',
  112: 'f1',
  113: 'f2',
  114: 'f3',
  115: 'f4',
  116: 'f5',
  117: 'f6',
  118: 'f7',
  119: 'f8',
  120: 'f9',
  121: 'f10',
  122: 'f11',
  123: 'f12',
  144: 'numlock',
  145: 'scrolllock',
  186: 'semicolon',
  187: 'equalsign',
  188: 'comma',
  189: 'dash',
  // 190: 'period',
  // 191: 'slash',
  192: 'graveaccent',
  220: 'backslash',
  222: 'quote',
};

CM.keyMap.basic.Up = 'goLineUpOrEmit';
CM.keyMap.basic.Down = 'goLineDownOrEmit';
CM.commands.goLineUpOrEmit = goLineUpOrEmit;
CM.commands.goLineDownOrEmit = goLineDownOrEmit;

export default class Editor extends React.Component {
  static propTypes = {
    autoCloseBrackets: React.PropTypes.bool,
    id: React.PropTypes.string,
    input: React.PropTypes.any,
    completion: React.PropTypes.bool,
    language: React.PropTypes.string,
    tabSize: React.PropTypes.number,
    lineNumbers: React.PropTypes.bool,
    lineWrapping: React.PropTypes.bool,
    onChange: React.PropTypes.func,
    matchBrackets: React.PropTypes.bool,
    theme: React.PropTypes.string,
    cmtheme: React.PropTypes.string,
    focused: React.PropTypes.bool,
    focusAbove: React.PropTypes.func,
    focusBelow: React.PropTypes.func,
  };

  static contextTypes = {
    store: React.PropTypes.object,
  };

  static defaultProps = {
    autoCloseBrackets: true, // automatically closes opening parens and quotations
    language: 'python',
    lineNumbers: false,
    matchBrackets: true, // highlights parens that are paired
    cmtheme: 'composition',
    focused: false,
  };

  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
    this.state = {
      source: this.props.input,
    };
    this.onChange = this.onChange.bind(this);

    this.hint = this.completions.bind(this);
    this.hint.async = true;

    // Remember the name of the theme that's applied so that when it changes we
    // can force codemirror to remeasure.
    this.theme = null;
  }

  componentDidMount() {
    // On first load, if focused, set codemirror to focus
    if (this.props.focused) {
      this.codemirror.focus();
    }

    const cm = this.codemirror.getCodeMirror();
    cm.on('topBoundary', this.props.focusAbove);
    cm.on('bottomBoundary', this.props.focusBelow);

    const keyupEvents = Rx.Observable.fromEvent(cm, 'keyup', (editor, ev) => ({ editor, ev }));

    keyupEvents
      .switchMap(i => Rx.Observable.of(i))
      .subscribe(({ editor, ev }) => {
        const cursor = editor.getDoc().getCursor();
        const token = editor.getTokenAt(cursor);

        if (!editor.state.completionActive &&
            !excludedIntelliSenseTriggerKeys[(ev.keyCode || ev.which).toString()] &&
            (token.type === 'tag' || token.type === 'variable' || token.string === ' ' ||
             token.string === '<' || token.string === '/') &&
            store.getState().app.executionState === 'idle') {
          editor.execCommand('autocomplete', { completeSingle: false });
        }
      });
  }

  componentWillReceiveProps(nextProps) {
    this.setState({
      source: nextProps.input,
    });
  }

  componentDidUpdate(prevProps) {
    if (this.props.focused && prevProps.focused !== this.props.focused) {
      this.codemirror.focus();
    } else if (!this.props.focused && prevProps.focused !== this.props.focused) {
      const cm = this.codemirror.getCodeMirror();
      cm.getInputField().blur();
    }

    if (this.theme !== this.props.theme) {
      this.theme = this.props.theme;
      this.codemirror.getCodeMirror().refresh();
    }
  }

  onChange(text) {
    if (this.props.onChange) {
      this.props.onChange(text);
    } else {
      this.setState({
        source: text,
      });
      this.context.store.dispatch(updateCellSource(this.props.id, text));
    }
  }

  completions(editor, callback) {
    if (!this.props.completion) {
      return;
    }

    const state = this.context.store.getState();
    const channels = state.app.channels;

    codeComplete(channels, editor)
      .subscribe(callback);
  }

  render() {
    const options = {
      autoCloseBrackets: this.props.autoCloseBrackets,
      mode: this.props.language,
      lineNumbers: this.props.lineNumbers,
      lineWrapping: this.props.lineWrapping,
      matchBrackets: this.props.matchBrackets,
      theme: this.props.cmtheme,
      autofocus: false,
      hintOptions: {
        hint: this.hint,
        completeSingle: false, // In automatic autocomplete mode we don't want override
        extraKeys: {
          Right: pick,
        },
      },
      extraKeys: {
        'Ctrl-Space': 'autocomplete',
      },
      indentUnit: this.props.tabSize,
      tabSize: this.props.tabSize,
    };
    return (

        <CodeMirror
          value={this.state.source}
          ref={(el) => { this.codemirror = el; }}
          className="cell_cm"
          options={options}
          onChange={this.onChange}
        />

    );
  }
}
<|endoftext|>


<commit_before>module.exports = {};<commit_msg>remove server-side views<commit_after><|endoftext|>