// func.js

const fn = {
  add: (num1, num2) => num1 + num2,
  getName: (callback) => {
    const name = "malza";
    setTimeout(() => {
      callback(name);
    }, 3000);
  },
};

module.exports = fn;
// func.test.js
const func = require("./func"); // func.js 요청

test("3초 후에 받아온 이름은 malza", () => {
  function callback(name) {
    expect(name).toBe("malza");
  }
  func.getName(callback);
});

// 성공! 근데?
// √ 3초 후에 받아온 이름은 malza (1 ms)
// 1 ms 라니? 3초후에 받아오라고 했는데?
expect(name).toBe("tom");
// 아니 이것도 통과된다. 왜?

// jest 는 실행의 끝에 다다르면 끝나버린다.
// 예정되어 있던 callback 함수가 실행되지 않고 끝나버린 것.

test("3초 후에 받아온 이름은 malza", (done) => { // done callback func를 전달해준다.
  function callback(name) {
    expect(name).toBe("tom");
    done(); // done 이 호출되기 전까지 jest 는 실행을 끝내지 않고 기다린다.
  }
  func.getName(callback);
});

// 성공!
// √ 3초 후에 받아온 이름은 malza (3002 ms)
// done() 을 호출하지 않으면 실패한다.
// × 3초 후에 받아온 이름은 malza (5002 ms) 5초동안 응답이 없어 timeout
// api 의 error를 감지하고 싶다면 try catch 문으로 감싸자
const fn = {
  add: (num1, num2) => num1 + num2,
  getName: (callback) => {
    const name = "malza";
    setTimeout(() => {
      //callback(name);
      throw new Error("서버 error 발생..");
    }, 3000);
  },
};

module.exports = fn;

====================================

const func = require("./func"); // func.js 요청

test("3초 후에 받아온 이름은 malza", (done) => {
  function callback(name) {
    try {
      expect(name).toBe("malza");
      done();
    } catch (e) {
      done();
    }
  }
  func.getName(callback);
});

// console.error
// Error: Uncaught [Error: 서버 error 발생..]
// promise 를 반환 해 보자.

// func.js
const fn = {
  add: (num1, num2) => num1 + num2,
  getName: (callback) => {
    const name = "malza";
    setTimeout(() => {
      callback(name);
    }, 3000);
  },
  getAge : ()=>{
    const age = 30;
    return new Promise((res, rej) =>{
      setTimeout(() => {
        res(age);
      }, 3000);
    })
  }
};

module.exports = fn;

====================================================================
// func.test.js
const func = require("./func"); // func.js 요청

test("3초 후에 받아온 나이는 30", () => {
  func.getAge().then((age) => {
    expect(age).toBe(30);
  });
});

// PASS
// √ 3초 후에 받아온 나이는 30 (1 ms)
// 또 1ms 로 끝났다. 이상이 있는 것.

// promise 를 사용한다면, test 에서 함수를 return 해줘야 한다.
test("3초 후에 받아온 나이는 30", () => {
  return func.getAge().then((age) => {    // return!
    expect(age).toBe(30);
  });
})

// PASS  ./func.test.js
//  √ 3초 후에 받아온 나이는 30 (3003 ms)

// matcher 를 사용할 수 있다.
test("3초 후에 받아온 나이는 30", () => {
  return expect(func.getAge()).resolves.toBe(30); // 위와 동일하다.
});
// rej 도 받아보자.
// func.js
const fn = {
  add: (num1, num2) => num1 + num2,
  getName: (callback) => {
    const name = "malza";
    setTimeout(() => {
      callback(name);
    }, 3000);
  },
  getAge: () => {
    const age = 30;
    return new Promise((res, rej) => {
      setTimeout(() => {
        rej("Error..!");  // rej 으로 error!
      }, 3000);
    });
  },
};

module.exports = fn;

====================================================================

// func.test.js
const func = require("./func"); // func.js 요청

test("3초 후에 Error 발생", () => {
  return expect(func.getAge()).rejects.toMatch("Error..!");
});

// PASS  ./func.test.js
//  √ 3초 후에 Error 발생 (3001 ms)
// async , await
// func.js
const fn = {
  add: (num1, num2) => num1 + num2,
  getName: (callback) => {
    const name = "malza";
    setTimeout(() => {
      callback(name);
    }, 3000);
  },
  getAge: () => {
    const age = 30;
    return new Promise((res, rej) => {
      setTimeout(() => {
        res(age);
      }, 3000);
    });
  },
};

// module.exports = fn;
====================================================================

// func.test.js
const func = require("./func"); // func.js 요청

test("3초 후에 받아올 나이는 30", async () => {
  const age = await func.getAge();
  expect(age).toBe(30);
//	await expect(func.getAge()).resolves.toBe(30); // resolves 도 가능하다.
});