본문 바로가기
JavaScript

TIL 0917 Testbuilder, 조건문, 리터럴, IIFE(Immediately invoked function expression)

by 짱닭 2020. 9. 17.
반응형

조건문

    /**
     * Maestro 앞자리 5018 5020 5038 6304 이고 length 12 ~ 19
     * 
     * China UnionPay 622126-622925 624-626 6282-6288 이고 length 16 ~ 19
     * 
     * Switch 4903 4905 4911 4936 564182 633110 6333 6759 length 16 18 19
     */

    if(['5018', '5020', '5038', '6304'].includes(cardNumber.substring(0,4)) //앞4자리가 배열값중 하나일때
    && (cardNumber.length >= 12 && cardNumber.length <= 19)/**길이판별 */){
      return 'Maestro';
    }

    if(( (Number(cardNumber.substring(0,6)) >= 622126 && Number(cardNumber.substring(0,6)) <= 622925) 
    || (Number(cardNumber.substring(0,4))>=6282 && Number(cardNumber.substring(0,4))<=6288)
    || (Number(cardNumber.substring(0,3))>=624 && Number(cardNumber.substring(0,3))<=626))/*앞자리 판별*/
    && (cardNumber.length >= 16 && cardNumber.length <= 19)/**길이판별 */){
      return 'China UnionPay';
    }

    if((['4903', '4905', '4911', '4936', '6333', '6759'].includes(cardNumber.substring(0,4))
    || ['564182', '633110'].includes(cardNumber.substring(0,6)))/**앞자리 판별 */
    && (cardNumber.length===16 || cardNumber.length===18 || cardNumber.length===19)/**길이판별 */){
      return 'Switch';
    }else if(cardNumber.slice(0, 1) === '4' && (cardNumber.length === 13 
      || cardNumber.length === 16 || cardNumber.length === 19)){
        return 'Visa';
    } 

주석의 조건을 만족시키기 위해 동일한 자릿수의 앞자리 조건은 배열에 담아 입력받은 cardNumber의 앞자리 4개가
배열에 담은 조건들 중 하나인지를 판별한다.

AND 연산자로 길이 또한 조건을 만족하는지 판별한다.

주석으로 앞, 뒤를 따로 떨어뜨려 놓으니 복잡한 조건을 알아보기가 쉬워졌다.

리터럴

describe("should support Switch", function() {
  let expect = chai.expect;
  let fourdigit=['4903', '4905', '4911', '4936', '6333', '6759'];
  let sixdigit=['564182', '633110'];

  //앞 4자리 맞는것
  for(let i=0; i < fourdigit.length; i++){
    it(`has a prefix of ${fourdigit[i]} and a length of 16`, function(){
      expect(detectNetwork(fourdigit[i]+"567890123456")).to.equal("Switch");
    });
  }
  for(let i=0; i < fourdigit.length; i++){
    it(`has a prefix of ${fourdigit[i]} and a length of 18`, function(){
      expect(detectNetwork(fourdigit[i]+"56789012345678")).to.equal("Switch");
    });
  }
  for(let i=0; i < fourdigit.length; i++){
    it(`has a prefix of ${fourdigit[i]} and a length of 19`, function(){
      expect(detectNetwork(fourdigit[i]+"567890123456789")).to.equal("Switch");
    });
  }

  //앞 6자리 맞는것
  for(let i=0; i < sixdigit.length; i++){
    it(`has a prefix of ${sixdigit[i]} and a length of 16`, function(){
      expect(detectNetwork(sixdigit[i]+"7890123456")).to.equal("Switch");
    });
  }
  for(let i=0; i < sixdigit.length; i++){
    it(`has a prefix of ${sixdigit[i]} and a length of 18`, function(){
      expect(detectNetwork(sixdigit[i]+"789012345678")).to.equal("Switch");
    });
  }
  for(let i=0; i < sixdigit.length; i++){
    it(`has a prefix of ${sixdigit[i]} and a length of 19`, function(){
      expect(detectNetwork(sixdigit[i]+"7890123456789")).to.equal("Switch");
    });
  }

리터럴을 이용한 또 다른 조건문 예시.

테스트 헬퍼 라이브러리

describe("Visa", function() {
  // Chai는 테스트에 필요한 헬퍼 함수들이 담긴 라이브러리입니다!
  // Chai는 이전에 만들었던 assert 함수와 동일한 기능을 하는 assert 함수를 제공합니다.
  // Chai가 제공하는 assert 함수를 어떻게 사용하는지 웹사이트의 공식 문서를 참고해보세요.
  //   http://chaijs.com/
  let assert = chai.assert;

  it("has a prefix of 4 and a length of 13", function() {
    assert(detectNetwork("4123456789012") === "Visa");
  });
describe("MasterCard", function() {
  // Chai는 좀 더 영어 문법에 가까운 코드로 테스트를 작성할 수 있게 도와줍니다.
  // Expect 문법은 그 중 한가지이며, 다른 문법도 있습니다.
  // 이와 관련해 더 알고 싶다면, 공식 문서를 참고하세요.
  //   http://chaijs.com/api/bdd/
  let expect = chai.expect;

  it("카드 앞 두자리가 51이고 카드번호 길이가 16", function() {
    expect(detectNetwork("5112345678901234")).to.equal("MasterCard");
  });
// expect 대신에 should라는 문법을 사용해서 스타일을 조금 변경할 수도 있습니다.
  // 사실 둘 중 어떤 것을 사용하는지는 중요하지 않습니다.
  // 스타일에 관련해서는 다음 사이트를 참조하세요. http://chaijs.com/guide/styles/
  // 다만 중요한 것은 스타일의 일관성을 유지하는 것입니다.
  // (우리는 공부를 하는 중이기 때문에 두가지 방법 모두를 사용해 보았습니다.)
  // 테스트를 작성하는 중에, 두가지 방법을 동시에 사용하려고 하면 진행되지 않을 것입니다.
  // expect나 should 둘 중에 한가지 방법을 선택해서 사용하세요.
  let should = chai.should();

  it("has a prefix of 54 and a length of 16", function() {
    detectNetwork("5412345678901234").should.equal("MasterCard");
  });

Immediately invoked function expression

즉시 호출되는 함수 표현식은 여러 가지 다른 방법으로 작성할 수 있다. 일반적인 관례는 함수 식(선택적으로 호출 연산자)과 함수 식(선택적으로 호출 연산자)을 그룹 연산자와 함께 괄호로 묶어서 파서에게 표현식을 기대하도록 명시적으로 지시하는 것이다. 그렇지 않으면 대부분의 상황에서 파서가 함수 키워드와 마주쳤을 때 함수 표현식이 아닌 함수 선언(문)으로 취급한다.

(function () { /* ... */ })();
(function () { /* ... */ }());
(() => { /* ... */ })(); // With ES6 arrow functions (though parentheses only allowed on outside)

There are other ways to enforce a function expression:

!function () { /* ... */ }();
~function () { /* ... */ }();
-function () { /* ... */ }();
+function () { /* ... */ }();
void function () { /* ... */ }();

In contexts where an expression is expected, wrapping in parentheses is not necessary:

var f = function () { /* ... */ }();
true && function () { /* ... */ }();
0, function () { /* ... */ }();

Passing variables into the scope is done as follows:

(function(a, b) { /* ... */ })("hello", "world");

Testbuilder 문제를 풀면서 IIFE가 필요했던 부분은
큰 block 스코프 안에서 작은 스코프로 나뉜 부분을
한번 더 감싸는 스코프가 필요했던 부분이다.

// Maestro, China UnionPay와 Switch를 검사하는 것은 Advanced 과제입니다.
// 원하시는 분들은 도전해보세요!
describe("Maestro", function() {
  let expect = chai.expect;


  (function () { 
    let adder='';
    for(let length=12; length <= 19; length++){
      it(`has a prefix of 5018 and a length of ${length}`, function() {
        expect(detectNetwork("501856789012"+adder)).to.equal("Maestro");
        adder=adder+'0';
      });
    }

  })();

  (function () { 
    let adder='';
    for(let length=12; length <= 19; length++){
      it(`has a prefix of 5020 and a length of ${length}`, function() {
        expect(detectNetwork("502056789012"+adder)).to.equal("Maestro");
        adder=adder+'0';
      });
    }
  })();

.
.
.

}

내 풀이상 adder 변수를 for문 전에 빈 문자열로 초기화해주는 과정이 반드시 필요했는데
반복적으로 쓰이는 adder를 위한 스코프가 따로 필요 했기에 IIFE를 이용했다.

IIFE를 이용하기 전엔 계속 스코프를 만들어보고 없애도보며 갖은 방법을 써보았지만 실패했다.
while(true) 스코프 안에 adder초기화 부분과 for문을 넣을까 고민하던 차에 IIFE가 생각났다.

describe("should support China UnionPay", function() {
  let expect = chai.expect;

  for(let prefix=622126; prefix <= 622925; prefix++){
    let adder='';
    for(let length=16; length<=19; length++){
      it(`has a prefix of ${prefix} and a length of ${length}`, function(){
        expect(detectNetwork(String(prefix)+'7890123456'+adder)).to.equal("China UnionPay");
        adder=adder+'0';
      });
    }
  }

  for(let prefix=624; prefix <= 626; prefix++){
      let adder='';
      for(let length=16; length<=19; length++){
        it(`has a prefix of ${prefix} and a length of ${length}`, function(){
          expect(detectNetwork(String(prefix)+'4567890123456'+adder)).to.equal("China UnionPay");
          adder=adder+'0';
        });
      }
    }
.
.
.


}

위 코드는 이중 for문으로 adder를 초기화하기 위한 스코프를 만들어준 것이다.

반응형

댓글