"use strict"
var __createBinding =
  (this && this.__createBinding) ||
  (Object.create
    ? function (o, m, k, k2) {
        if (k2 === undefined) k2 = k
        Object.defineProperty(o, k2, {
          enumerable: true,
          get: function () {
            return m[k]
          }
        })
      }
    : function (o, m, k, k2) {
        if (k2 === undefined) k2 = k
        o[k2] = m[k]
      })
var __setModuleDefault =
  (this && this.__setModuleDefault) ||
  (Object.create
    ? function (o, v) {
        Object.defineProperty(o, "default", { enumerable: true, value: v })
      }
    : function (o, v) {
        o["default"] = v
      })
var __importStar =
  (this && this.__importStar) ||
  function (mod) {
    if (mod && mod.__esModule) return mod
    var result = {}
    if (mod != null)
      for (var k in mod)
        if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
          __createBinding(result, mod, k)
    __setModuleDefault(result, mod)
    return result
  }
Object.defineProperty(exports, "__esModule", { value: true })
exports.assert = exports.suite = exports.testM = exports.test = void 0
const tracing_1 = __importStar(require("../../Tracing"))
const fileName_1 = "(@effect-ts/system): _src/Testing/Api/index.ts"
const List = __importStar(require("../../Collections/Immutable/List"))
const T = __importStar(require("../../Effect"))
const Fiber_1 = require("../../Fiber")
const Function_1 = require("../../Function")
const M = __importStar(require("../../Managed"))
const O = __importStar(require("../../Option"))
const makeAssertionValue = __importStar(require("../AssertionValue/makeAssertionValue"))
const sameAssertion_ = __importStar(require("../AssertionValue/sameAssertion"))
const BA = __importStar(require("../BoolAlgebra"))
const FailureDetails_1 = require("../FailureDetails")
const Spec = __importStar(require("../Spec"))
const TA = __importStar(require("../TestAnnotation"))
const TestAnnotationMap_1 = require("../TestAnnotationMap")
const TF = __importStar(require("../TestFailure"))
const TS = __importStar(require("../TestSuccess"))
function test(label, __trace) {
  return (assertion) =>
    testM(label, __trace)(() => T.succeedWith(assertion, fileName_1 + ":24:46"))
}
exports.test = test
function testM(label, __trace) {
  return (assertion) =>
    Spec.annotate(
      TA.location,
      __trace ? List.of(new Fiber_1.SourceLocation(__trace)) : List.empty()
    )(Spec.test(label, ZTest(assertion), TestAnnotationMap_1.TestAnnotationMap.empty))
}
exports.testM = testM
function suite(label) {
  return (...tests) =>
    Spec.suite(label, M.succeed(tests, fileName_1 + ":44:35"), O.none)
}
exports.suite = suite
function ZTest(assertion) {
  return T.foldCauseM_(
    T.suspend(assertion, fileName_1 + ":51:14"),
    (c) => T.fail(TF.halt(c), fileName_1 + ":53:20"),
    (r) =>
      O.fold_(
        BA.failures(r),
        () => T.succeed(new TS.Succeeded(BA.unit), fileName_1 + ":57:26"),
        (failures) => T.fail(TF.assertion(failures), fileName_1 + ":58:31")
      ),
    fileName_1 + ":52:17"
  )
}
function assert(value, expression = O.none, sourceLocation = O.none) {
  return (assertion) =>
    traverseResult(
      () => value,
      assertion.run(() => value),
      assertion,
      expression,
      sourceLocation
    )
}
exports.assert = assert
function traverseResult(value, assertResult, assertion, expression, sourceLocation) {
  return BA.chain((fragment) => {
    function loop(whole, failureDetails) {
      if (sameAssertion_.sameAssertion_(whole, failureDetails.assertion[0])) {
        return BA.success(failureDetails)
      }
      const fragment = whole.result()
      const result = BA.isSuccess(fragment) ? fragment : fragment["!"]
      return BA.chain_(result, (fragment) =>
        loop(
          fragment,
          new FailureDetails_1.FailureDetails([whole, ...failureDetails.assertion])
        )
      )
    }
    return loop(
      fragment,
      new FailureDetails_1.FailureDetails([
        makeAssertionValue.makeAssertionValue(
          assertion,
          value,
          () => assertResult,
          expression,
          sourceLocation
        )
      ])
    )
  })(assertResult)
}
//# sourceMappingURL=index.js.map
