import &StandardImport, &CaffeineScript, {}
  &path
  fs: &fsExtra

sourceRootName = "AliceInLove"
sourceRoot = "/home/alice/#{sourceRootName}"
sourcePath = "#{sourceRoot}/source/AliceInLove/Lib"
sourceFileName = "myFile"
sourceFileExtension = "caf"
sourceFile = "#{sourcePath}/#{sourceFileName}.#{sourceFileExtension}"

initialFs =
  tmp: {}
  home: alice: AliceInLove:
    "package.json": "{}"
    source: AliceInLove:
      Lib: "#{sourceFileName}.caf": "&standard_import"
      "StandardImport.caf": ":foo"

describe
  pre: ->
    test "JEST-needs-this-for-mock-fs-to-workfoo" ->

  basic: ->
    beforeAll ->
      fs.setMockFileStructure initialFs

    fakeInfo =
      compiler:
        name: "TestCompiler"
        version: "1.2.3"
      source: "My source code."
      sourceFile: sourceFile
      compiled: js: "console.log('My source code'.);"

    test "getFileName", ->
      cacheFileName = CompileCache.getFileName fakeInfo
      assert.match cacheFileName, CompileCache.compileCacheFileNameRoot
      assert.match cacheFileName, "TestCompiler"
      assert.match cacheFileName, sourceRootName
      assert.match cacheFileName, sourceFileName
      assert.match cacheFileName, sourceFileExtension

    test "cache", ->
      cacheKey = CompileCache.cache fakeInfo
      assert.eq fakeInfo.compiled, CompileCache.fetch(objectWithout fakeInfo, "compiled").compiled

    test "different compilerOptions generates different cache filenames", ->
      assert.neq
        CompileCache.getFileName merge fakeInfo, compilerOptions: {}
        CompileCache.getFileName merge fakeInfo, compilerOptions: prettier: true

    test "compilerOptions with different order still generates same cache filenames", ->
      assert.eq
        CompileCache.getFileName merge fakeInfo, compilerOptions: a: 1, b: 2
        CompileCache.getFileName merge fakeInfo, compilerOptions: b: 2, a: 1

  FileCompiler: ->
    beforeAll ->
      fs.setMockFileStructure initialFs

    chainedTest "init" -> WorkingCache.resetWorkingCache()
    .thenTest
      "initial compileFile", ->
        FileCompiler.compileFile sourceFile, cache: true
        .then ({output}) ->
          assert.jsFalse output.cached

      "cached compileFile", ->
        FileCompiler.compileFile sourceFile, cache: true
        .then ({output}) ->
          assert.true output.cached

      "move moduleDependency triggers recompile", ->
        outputFilename = path.join path.dirname(sourceFile), "StandardImport.caf"
        fs.writeFile outputFilename, ":bar"
        .then ->
          WorkingCache.resetWorkingCache()
          FileCompiler.compileFile sourceFile, cache: true
        .then ({output}) ->
          assert.jsFalse output.cached
