首页 \ 问答 \ 使用promises并跳过代码时,Mocha测试会超时,为什么?(Mocha test times out when using promises and skips over code, why?)

使用promises并跳过代码时,Mocha测试会超时,为什么?(Mocha test times out when using promises and skips over code, why?)

我一直试图连续2天运行这个测试,我无法弄清楚它有什么问题:

/*eslint-env mocha */
// var expect = require('chai').expect;
var chai = require('chai');
var chaiAsPromised = require("chai-as-promised");
var expect = chai.expect;
var Promise = require('bluebird');
var Archive = require('../lib/archive');
var path = require('path');
var fs = Promise.promisifyAll(require('fs-extra'));
var globAsync = Promise.promisify(require('glob'));
var tar = require('tar-fs');
var zlib = Promise.promisifyAll(require('zlib'));

chai.use(chaiAsPromised);

describe('Archive', function() {
  var pkg;
  var archive_location;
  var subject;

  beforeEach(function() {
    pkg = {
      name: 'test_0790feebb1',
      recipient_name: 'Test',
      files: {
        letter: '../documents/letters/test/letter.tex',
        resume: '../documents/cover/cover.tex'
      },
      compiled_files: {
        package: '../documents/letters/test/test.pdf'
      }
    };
    archive_location = path.resolve('archives/test_0790feebb1.tar.gz'); 

    subject = new Archive(pkg);
  });

  after(function() {
    return globAsync('archives/test*')
      .each(function(filename) {
        return fs.removeAsync(filename);
      });
  });

  describe('#make', function() {
    it('has the correct directory structure', function() {
      // debugger;
      var tmp_extract_path = path.resolve('test/.tmp');
      var tarPromise = function(data) {
        console.log('tarP'); // never run
        return new Promise(function(reject, resolve) {
          data
            .pipe(zlib.Unzip())
            .pipe(tar.extract(tmp_extract_path))
            .on('error', reject)
            .on('end', resolve);
        });
      };

      var verifyDir = function() {
        console.log('verD'); // never run
        return Promise.all([
            'code',
            'pdf',
            'code/repo',
            'code/documents',
            'code/documents/letters',
            'code/documents/letters/test',
            'code/documents/letters/shared',
            'code/documents/cover',
            'code/documents/letters'
        ].map(function(subpath) {
          return fs.statAsync(path.resolve(tmp_extract_path, subpath));
        }));
      };

      return fs.createReadStreamAsync(archive_location)
        .then(function(data) { return tarPromise(data); })
        .then(function() { return verifyDir(); })
        .then(function(files) {
          console.log(files); // never run
          return expect(true).to.be.true;
        })
        .catch(function(e) { console.log(e); });
    });
  });
});

各种console.log甚至从未执行过,最终测试时间没有任何错误或堆栈跟踪。

我不知道我做错了什么,承诺现在伤害了我的大脑。 当我使用节点检查器运行代码并取消注释断点时,我可以看到this._runnable._trace值是"done() called multiple times" 。 我不知道这是否是一个实际的错误,也不知道如果这是一个错误,它不会抛出异常。 我无法解释为什么这甚至发生,因为我不再使用任何done()回调和promises,我的测试以function()开头而不是function(done)就像异步测试一样

有任何想法吗?


I have been trying to run this test for 2 days straight now and I can't figure what is wrong with it:

/*eslint-env mocha */
// var expect = require('chai').expect;
var chai = require('chai');
var chaiAsPromised = require("chai-as-promised");
var expect = chai.expect;
var Promise = require('bluebird');
var Archive = require('../lib/archive');
var path = require('path');
var fs = Promise.promisifyAll(require('fs-extra'));
var globAsync = Promise.promisify(require('glob'));
var tar = require('tar-fs');
var zlib = Promise.promisifyAll(require('zlib'));

chai.use(chaiAsPromised);

describe('Archive', function() {
  var pkg;
  var archive_location;
  var subject;

  beforeEach(function() {
    pkg = {
      name: 'test_0790feebb1',
      recipient_name: 'Test',
      files: {
        letter: '../documents/letters/test/letter.tex',
        resume: '../documents/cover/cover.tex'
      },
      compiled_files: {
        package: '../documents/letters/test/test.pdf'
      }
    };
    archive_location = path.resolve('archives/test_0790feebb1.tar.gz'); 

    subject = new Archive(pkg);
  });

  after(function() {
    return globAsync('archives/test*')
      .each(function(filename) {
        return fs.removeAsync(filename);
      });
  });

  describe('#make', function() {
    it('has the correct directory structure', function() {
      // debugger;
      var tmp_extract_path = path.resolve('test/.tmp');
      var tarPromise = function(data) {
        console.log('tarP'); // never run
        return new Promise(function(reject, resolve) {
          data
            .pipe(zlib.Unzip())
            .pipe(tar.extract(tmp_extract_path))
            .on('error', reject)
            .on('end', resolve);
        });
      };

      var verifyDir = function() {
        console.log('verD'); // never run
        return Promise.all([
            'code',
            'pdf',
            'code/repo',
            'code/documents',
            'code/documents/letters',
            'code/documents/letters/test',
            'code/documents/letters/shared',
            'code/documents/cover',
            'code/documents/letters'
        ].map(function(subpath) {
          return fs.statAsync(path.resolve(tmp_extract_path, subpath));
        }));
      };

      return fs.createReadStreamAsync(archive_location)
        .then(function(data) { return tarPromise(data); })
        .then(function() { return verifyDir(); })
        .then(function(files) {
          console.log(files); // never run
          return expect(true).to.be.true;
        })
        .catch(function(e) { console.log(e); });
    });
  });
});

The various console.log never even get executed and eventually the test times out without any error or stack trace.

I have no idea what I am doing wrong and promises hurt my brain now. When I run the code with node inspector and uncomment the breakpoint, I can see that he value of this._runnable._trace is "done() called multiple times". I have no idea if this is an actual error nor why it doesn't throw an exception if that's an error. I can't explain either why this is even happening since I am not using any done() callbacks anymore with promises and that my test starts with function() and not function(done) like an async test would

Any ideas?


原文:https://stackoverflow.com/questions/32876127
更新时间:2022-08-17 18:08

最满意答案

如果你想学习汇编,我会认真地建议编写C或C ++代码并检查生成的程序集以便选择目标。

这会给你一个基础。

#include <cmath>

double compute(double x, double degree, double radius) {
  return x + std::sin(degree) * radius;
}

提供以下LLVM IR:

define double @_Z7computeddd(double %x, double %degree, double %radius)
                             nounwind uwtable readnone
{
  %1 = tail call double @sin(double %degree) nounwind readnone
  %2 = fmul double %1, %radius
  %3 = fadd double %2, %x
  ret double %3
}

declare double @sin(double) nounwind readnone

这给出了以下组件:

    .text
    .globl  _Z7computeddd
    .align  16, 0x90
    .type   _Z7computeddd,@function
_Z7computeddd:                          # @_Z7computeddd
.Ltmp1:
    .cfi_startproc
# BB#0:
    subq    $24, %rsp
.Ltmp2:
    .cfi_def_cfa_offset 32
    movsd   %xmm2, 16(%rsp)         # 8-byte Spill
    movsd   %xmm0, 8(%rsp)          # 8-byte Spill
    movaps  %xmm1, %xmm0
    callq   sin
    mulsd   16(%rsp), %xmm0         # 8-byte Folded Reload
    addsd   8(%rsp), %xmm0          # 8-byte Folded Reload
    addq    $24, %rsp
    ret
.Ltmp3:
    .size   _Z7computeddd, .Ltmp3-_Z7computeddd
.Ltmp4:
    .cfi_endproc
.Leh_func_end0:


    .section    ".note.GNU-stack","",@progbits

请注意,还有一个sin召唤。


If you want to learn assembly, I would seriously recommend writing C or C++ code and inspecting the generated assembly for your target of choice.

This will give you a basis.

#include <cmath>

double compute(double x, double degree, double radius) {
  return x + std::sin(degree) * radius;
}

Gives the following LLVM IR:

define double @_Z7computeddd(double %x, double %degree, double %radius)
                             nounwind uwtable readnone
{
  %1 = tail call double @sin(double %degree) nounwind readnone
  %2 = fmul double %1, %radius
  %3 = fadd double %2, %x
  ret double %3
}

declare double @sin(double) nounwind readnone

Which gives the following assembly:

    .text
    .globl  _Z7computeddd
    .align  16, 0x90
    .type   _Z7computeddd,@function
_Z7computeddd:                          # @_Z7computeddd
.Ltmp1:
    .cfi_startproc
# BB#0:
    subq    $24, %rsp
.Ltmp2:
    .cfi_def_cfa_offset 32
    movsd   %xmm2, 16(%rsp)         # 8-byte Spill
    movsd   %xmm0, 8(%rsp)          # 8-byte Spill
    movaps  %xmm1, %xmm0
    callq   sin
    mulsd   16(%rsp), %xmm0         # 8-byte Folded Reload
    addsd   8(%rsp), %xmm0          # 8-byte Folded Reload
    addq    $24, %rsp
    ret
.Ltmp3:
    .size   _Z7computeddd, .Ltmp3-_Z7computeddd
.Ltmp4:
    .cfi_endproc
.Leh_func_end0:


    .section    ".note.GNU-stack","",@progbits

Note that there is still a sin call.

相关问答

更多
  • 如果你想学习汇编,我会认真地建议编写C或C ++代码并检查生成的程序集以便选择目标。 这会给你一个基础。 #include double compute(double x, double degree, double radius) { return x + std::sin(degree) * radius; } 提供以下LLVM IR: define double @_Z7computeddd(double %x, double %degree, double %radius) ...
  • 它编译的代码不是汇编,而是直接的机器代码,至少在链接时优化之后。 您在调试时看到的是对当前正在执行的机器代码进行即时反汇编 。 因此,它没有额外的结构,比如标签,宏等,这样您就可以在高级汇编程序中找到它们,因为这些额外的信息在生成机器码时会丢失(或者,更准确地说,永远不会出现) 。 如果你的意思是语法,Visual Studio将显示Intel语法中的汇编指令,这与AT&T语法不同,这是GCC和GNU汇编程序的默认语法。 事实上,这也可能是胡言乱语。 如果jmp不对齐(x86指令是可变长度的),或者不包含可 ...
  • 因为它是一个浮点数组,每个浮点数占4个字节,你应该将索引乘以4.还要注意C调用约定要求调用者释放参数,因此你的“ ret 8 ”是错误的。 mov eax, esi在最后是无关紧要的。 Since it's an array of floats each taking 4 bytes you should multiply the index by 4. Also note that C calling convention mandates that the caller will free the ar ...
  • 查看Doxygen FAQ的问题12。 你正在处理纯粹的汇编文件,还是C源代码中的内联汇编? 假设前者,你必须编写一个输入过滤器来将汇编代码转换成类C(更简单),或者编写新的解析器(更难)。 See question 12 of the Doxygen FAQ. Are you dealing with pure assembly files, or inline assembly inside C sources? Assuming the former, you'll have to either wr ...
  • 是的,大多数时候。 首先,从错误的假设开始,低级语言(本例中的程序集)总是会产生比高级语言(C ++和C在这种情况下)更快的代码。 这不是真的。 C代码总是比Java代码快吗? 不,因为有另一个变量:程序员。 编写代码和建筑细节知识的方式大大影响了性能(正如你在这种情况下看到的)。 您可以随时制作一个示例,其中手工汇编代码比编译代码更好,但通常它是虚构示例或单个例程,而不是500.000+行的C ++代码的真正程序)。 我认为编译器将生成更好的汇编代码95%, 有时候,只有少数时候,您可能需要为少数,短期, ...
  • 将参数传递给gcdasm() 两个int参数通过寄存器传递,而不是堆栈。 第一个和第二个参数分别在rdi和rsi的下半部分(即: edi和esi )中传递。 因此,通过将edi和esi分别扩展为rax和rbx ,可以将传递的参数加载到这些寄存器中: movsx rax, edi ;load rax with x movsx rbx, esi ;load rbx with y 但是请注意, rbx不是一个临时寄存器 ,因此被调用者需要在修改它之前保存它,然后在离开gcdasm函数之前恢复它。 你可以简单 ...
  • 它不需要,但大部分都是这样做的,因为可以将相同的汇编程序(程序)用于C / C ++ /任意汇编器编译器的输出。 例如,g ++首先生成汇编代码(可以使用-S开关查看生成的汇编程序)。 MSVC也是这样( /FAs )。 It doesn't have to, but most do it anyway, as the same assembler (program) can be used for the output of the C/C++/whatever-to-assembler compiler ...
  • #if defined(_MSC_VER) // visual c #elif defined(__GCCE__) // gcce #else // unknown #endif 我的内联汇编程序技能很生疏,但它的工作原理如下: __asm { // some assembler code } 但只要使用rdtsc,你就可以使用内在函数: unsigned __int64 counter; counter = __rdtsc(); http://msdn.microsoft.com/en-us/lib ...
  • 让我们分解一下: .file "delta.c" 编译器使用它来告诉程序集来自的源文件。 这对汇编程序来说并不重要。 .section .rodata 这开始一个新的部分。 “rodata”是“只读数据”部分的名称。 本部分最终将数据写入将内存映射为只读数据的可执行文件。 可执行映像的所有“.rodata”页面最终都将由加载映像的所有进程共享。 通常,源代码中的任何“编译时常量”都无法被优化到汇编内部函数中,最终将被存储在“只读数据段”中。 .LC0: .string "%d" .L ...
  • @ modelnine的注释是正确的 - lea用于简化循环中的赋值。 你有: x = ii - 2; 并且lea (加载有效地址)指令正在有效地执行: esi = &(*(eax - 2)); &和*相互抵消(这很重要 - 在这种情况下取消引用eax可能会导致问题),所以你得到: esi = eax - 2; 正是你的C代码试图做的事情。 @modelnine's comment is correct - the lea is being used to simplify the assignmen ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)