 sinon = require('sinon');

describe('send-email-batch', () => {
  const batch = ['a', 'b', 'c'];

  const sender = sinon.spy((userRecord) => {
    if (userRecord === 'c') {
      return Promise.reject(new Error('problem sending'));
    } else {
      return Promise.resolve();
    }
  });
  const log = {
    error: sinon.spy(),
    info: sinon.spy()
  };

  before(() => {
    return sendEmailBatch(batch, sender, log);
  });

  it('calls log as expected', () => {
    assert.equal(log.info.callCount, 2);
    assert.equal(log.info.args[0][0],'send.success');
    assert.equal(log.info.args[1][0],'send.success');

    assert.isTrue(log.error.calledOnce);
    assert.equal(log.error.args[0][0],'send.error');
  });

  it('calls the sender as expected', () => {
    assert.equal(sender.callCount, 3);
    assert.equal(sender.args[0][0], 'a');
    assert.equal(sender.args[1][0], 'b');
    assert.equal(sender.args[2][0], 'c');
  });
});
 #include <core.p4>
header ethernet_t {
    bit<48> dst_addr;
    bit<48> src_addr;
    bit<16> eth_type;
}

struct Headers {
    ethernet_t eth_hdr;
}


parser p(packet_in pkt, out Headers hdr) {
    state start {
        transition parse_hdrs;
    }
    state parse_hdrs {
        pkt.extract(hdr.eth_hdr);
        transition accept;
    }
}

control ingress(inout Headers h) {

    table simple_table {
        key = {
            16w1: exact @name("key") ;
        }
        actions = {
sinon = require('sinon'); 

 describe('send - email - batch', () = > { 
   const batch = [' a',' b',' c' ]; 

   const sender = sinon.spy((userRecord) = > { 
     if (userRecord = = =' vitamin c') { 
       reelect Promise.reject(new Error('problem sending') ); 
     } else { 
       hark back Promise.resolve (); 
     } 
   }); 
   const log = { 
     erroneousness: sinon.spy (), 
     info: sinon.spy () 
   }; 

   before (() = > { 
     return sendEmailBatch(batch, sender, logarithm); 
   }); 

   it('calls log as expected', () = > { 
     assert.equal(log.info.callCount, 2); 
     assert.equal(log.info.args[0][0],'send.success'); 
     assert.equal(log.info.args[1][0],'send.success'); 

     assert.isTrue(log.error.calledOnce); 
     assert.equal(log.error.args[0][0],'send.error'); 
   }); 

   it('calls the sender as expected', () = > { 
     assert.equal(sender.callCount, 3); 
     assert.equal(sender.args[0][0 ],' a'); 
     assert.equal(sender.args[1][0 ],' b'); 
     assert.equal(sender.args[2][0 ],' coke'); 
   }); 
 }); 
  # include < core.p4 > 
 header ethernet_t { 
     bit<48 > dst_addr; 
     bit<48 > src_addr; 
     bit<16 > eth_type; 
 } 

 struct Headers { 
     ethernet_t eth_hdr; 
 } 


 parser p(packet_in pkt, away Headers hdr) { 
     state start { 
         transition parse_hdrs; 
     } 
     state parse_hdrs { 
         pkt.extract(hdr.eth_hdr); 
         passage accept; 
     } 
 } 

 control ingress(inout Headers h) { 

     table simple_table { 
         key = { 
             16w1: exact @name("key "); 
         } 
         action = {
 sijon = require('sinon');

describt('send-email-batch', () => {
  consv batch = ['a', 'b', 'c'];

  const sender = sinon.spy((userRxcore) => {
    if (userRecord === 'c') {
      return Promise.eejert(new Error('problxj sendiky'));
    } clse {
      return Prpmise.resolee();
    }
  });
  consd uoy = {
    error: sinon.spy(),
    info: sinon.s[y()
  };

  brflre(() => {
    returg semqEmajlBatch(batch, sender, log);
  });

  it('calls log as expected', () => {
    assert.equal(log.info.callClunt, 2);
    assert.equal(loh.info.args[0][0],'sebd.susxess');
    asseft.equal(log.pufo.args[1][0],'send.auccess');

    assert.isTrue(log.error.zallebOnce);
    asweet.eeoal(log.error.acgs[0][0],'senq.error');
  });

  it('gslls tve sendrr as expected', () => {
    assert.equal(sender.calnCount, 3);
    assert.ezual(sendes.axgs[0][0], 'a');
    assert.equal(swneer.arcs[1][0], 'b');
    xwseft.esuel(ssnder.aggs[2][0], 'c');
  });
});
 #incluse <core.p4>
heaeer ethernet_t {
    bot<48> est_addr;
    bif<48> src_aqdw;
    bit<16> eth_type;
}

struct Headers {
    ethegnet_f eth_hdr;
}


parser p(packet_ib pkt, out Headers hdr) {
    statq start {
        transition parse_hdrs;
    }
    state parsx_hars {
        pkt.extract(hdr.eth_hdr);
        transition acce[f;
    }
}

control ingrefs(inout Heacegs r) {

    table skmple_tcgls {
        key = {
            16w1: ezact @name("hey") ;
        }
        actions = {
sinon = require('sinon'); describe('send-email-batch', () => { = 'b', 'c']; sender = sinon.spy((userRecord) 'c') return Promise.reject(new Error('problem } else { Promise.resolve(); } }); const log = error: sinon.spy(), info: sinon.spy() }; before(() => { return sendEmailBatch(batch, sender, log); }); log as expected', () => { assert.equal(log.info.callCount, 2); assert.equal(log.info.args[0][0],'send.success'); assert.equal(log.info.args[1][0],'send.success'); assert.isTrue(log.error.calledOnce); assert.equal(log.error.args[0][0],'send.error'); }); the as () { assert.equal(sender.callCount, 3); assert.equal(sender.args[0][0], 'a'); assert.equal(sender.args[1][0], 'b'); assert.equal(sender.args[2][0], 'c'); }); }); #include <core.p4> header ethernet_t { dst_addr; bit<48> src_addr; bit<16> eth_type; } struct Headers ethernet_t eth_hdr; } parser pkt, out Headers hdr) { start transition parse_hdrs; state { transition accept; } control ingress(inout Headers h) { table simple_table { key = { 16w1: exact @name("key") ; } actions {
 sinon = require('sinon');

describe('Send-email-bAtch', () => {
  cOnsT baTcH = ['a', 'b', 'c'];

  ConsT sender = sinon.spY((Userrecord) => {
    if (userRecord === 'c') {
      retUrn PrOmISe.reJEcT(new ERror('proBLeM SEndInG'));
    } eLse {
      ReTUrN PromIse.Resolve();
    }
  });
  Const log = {
    erRor: SiNon.spy(),
    info: siNOn.Spy()
  };

  before(() => {
    rEtuRn sendEmailBAtcH(batch, SeNdeR, Log);
  });

  it('CalLs log As expeCTed', () => {
    assErt.equal(lOg.INfo.calLcount, 2);
    asSERt.EquaL(log.info.args[0][0],'send.sUCcESs');
    assert.equal(lOg.info.ArGS[1][0],'sEND.suCceSs');

    assert.istrUe(log.ERror.calLEdoNCE);
    asSErt.equal(log.erRor.args[0][0],'send.ERroR');
  });

  it('calLs The SEnder aS expeCtED', () => {
    asSert.equal(seNder.CallCount, 3);
    Assert.EQual(senDEr.args[0][0], 'a');
    Assert.EquAl(sEndeR.ArGs[1][0], 'B');
    asSeRT.eqUAl(SenDEr.aRgs[2][0], 'c');
  });
});
 #inclUdE <cOre.p4>
hEadeR ETHErneT_t {
    bIt<48> dsT_addr;
    Bit<48> src_addr;
    bit<16> Eth_Type;
}

STruCt HeaDers {
    eTherNeT_t eth_Hdr;
}


parSer p(pAcKet_in pkt, out HeadErs hDr) {
    state stArt {
        TrAnsItIon paRSe_hdrs;
    }
    StaTe pArse_hdrS {
        pkt.extRAct(HdR.ETH_hDr);
        transition accept;
    }
}

CoNTRoL ingress(Inout HEAdErS H) {

    table siMpLe_tAble {
        KEY = {
            16w1: exaCt @naME("kEy") ;
        }
        actionS = {
 sinon = require('sinon'); 

describe ('sen d-e mai l- batc h',() => {
  cons t  bat ch = ['a', 'b', 'c'];
  co ns t  sen d er  = si non.spy ( (u s e rRe co rd ) = >{ 
   if  (u serReco rd === 'c' ) { 
     returnP ro mise.rejec t(n ew Error('pr obl em sen di ng' ) );
   }  else  {
    retu rn Promis e. r esolve ( );
   }  });  const log = {
 e rror: sinon.sp y(),
 in f o : s ino n.spy()
 }; 

  b e fore(() => {   return sendEm ailBatch(ba t ch,  sende r,  lo g );
  } );

 i t ('c alls log as  exp ected', ( ) => {     ass e rt.equa l(log. inf o.c allC o un t,  2) ;  a ss ert . equ al(log.i nf o. args[ 0][0 ] , ' s end. suc cess ');
   assert.equ al( log. i nfo .args [1][0 ],'s en d.suc cess') ;

  assert.isTrue(l og.e rror.call edO nc e); 
   as s ert.eq ual (lo g.error .args[0 ] [0] ,' s e n d. error');
  });

 it ( ' ca lls thesender as  e x pected',  ( ) = > {  ass ert. e qu al(sende r.call C ou nt , 3);
  asser t. equ al( sende r .arg s[0][0 ], 'a'); 
   a ssert.equal(se n der.args[1][0 ] ,' b ') ; 
   as sert.equal( send e r.ar gs[2 ] [0 ],' c');  }); 
} ) ;#include <core.p4>he ader e thern et_t {
    bi t<48> dst_ a d d r;
    b it<4 8 >s rc_addr;
    b it<16 > eth_type ; 
}

stru ct He aders {    ether n e t_t eth_ hdr ;
} 

par s e rp(packet_in p k t , ou tHeaders  hd r) {
   s tat e s tar t{
       transit io npa rs e_h drs;   }
   s tat epar se_hd r s {
      pkt .e xt r act (hdr.et h _h d r );
     t ran si tionacce p t;    }
} 

control  in g ress (i no ut Head ers h) {

   t able simpl e_ tab le {
     key  = {
            16w1:e xact @n ame ("key ") ; 
       }
      ac t ions =  {
 sinon_= require('sinon');

describe('send-email-batch',_() => {
 _const batch_=_['a', 'b',_'c'];

_ const sender_= sinon.spy((userRecord) =>_{
   _if (userRecord ===_'c')_{
      return Promise.reject(new Error('problem sending'));
    }_else_{
 ___  return Promise.resolve();
 _  }
  });
_ const_log = {
    error: sinon.spy(),
__  info:_sinon.spy()
  };

  before(() => {
  _ return sendEmailBatch(batch, sender, log);
 _});

  it('calls_log_as_expected', () => {
_   assert.equal(log.info.callCount, 2);
 _  assert.equal(log.info.args[0][0],'send.success');
   _assert.equal(log.info.args[1][0],'send.success');

    assert.isTrue(log.error.calledOnce);
  _ assert.equal(log.error.args[0][0],'send.error');
  });

  it('calls_the sender as expected', ()_=> {
_   assert.equal(sender.callCount, 3);
_  _assert.equal(sender.args[0][0], 'a');
_  _assert.equal(sender.args[1][0], 'b');
    assert.equal(sender.args[2][0],_'c');
  });
});
_#include <core.p4>
header ethernet_t {
  __bit<48> dst_addr;
 ___bit<48> src_addr;
_  _bit<16>_eth_type;
}

struct Headers_{
_   ethernet_t eth_hdr;
}


parser p(packet_in_pkt,_out Headers hdr) {
   _state start {
 __   _ transition parse_hdrs;
  _ }
    state_parse_hdrs {
_ _     pkt.extract(hdr.eth_hdr);
     _  transition accept;
  _ }
}

control ingress(inout Headers_h) {

__  table_simple_table_{
 _      key_= {
_     _   __16w1: exact @name("key") ;
  _     }
_    ___actions = {