Karma: any guide for writing karma plugins?

Created on 25 Nov 2014  ·  22Comments  ·  Source: karma-runner/karma

more detail

backlog

Most helpful comment

I also expecting this.

Developing Plugins

The best way to understand how this works is to take a look at some of the existing plugins

existing plugins can be wrong, have existing bug, also possibly not utilize all functionality core karma offers.

Public Api

point from @atian25

  • seq
    I also need that, if it stand for sequence
  • concept
    clear, but i expecting deeper explanation

I like to suggest updating the documentation, especially FAQ and public API.

I hope when the documentation improved. Then when it did we got benefit that existing issues and bug are easier to tackle.

All 22 comments

@atian25 you can use how example any plugin from karma-runner.

I want to get more detail , such as plugin seq, concept

The examples are quite simple and represent base concept

I want to get more detail , such as plugin seq, concept

Karma is assembled by Dependency Injection and a plugin is just an additional DI module (see node-di for more), that can be loaded by Karma. Therefore it can asks for pretty much any Karma component and interact with it.

Doc

sorry, had read some plugin source, but still have some question:

  • what is the *.wrapper ?
  • diff between framework and preprocessors?
  • preprocessors is process one file or can modify all file such as deps?

what is the *.wrapper

@vojtajina separate adapter on two files:
adapter.js - contain source code. Where all private functions and variables are public.
adapter.wrapper - This file _wraps_ andapter.js to closure. It allow protect private methods.
This approach _makes it easier to test private methods_. But this is only one approach.

diff between framework and preprocessors

  • framework - is _adapter between_ karma and some test framework. Usually most of the framework code executed on the _client_(in browser).
  • preprocessor - work with files on the _server_. How input it take file content and file object, how output it should return content of the file.

preprocessors is process one file or can modify all file such as deps

Function which returns preprocessor factory work only with _one file_. But if you want get access to all files you can inject it in you preprocessor factory <- (parameters _fileList_ and _files_)

P.S. If you want more deeper understanding core concepts of the karma I recommend read this. :)

3x

sorry, try for a while.

I want to compile all src to dist using my tools fis(something like grunt), then update karma files to the dist.

  1. should I write a preprocessors ?
  2. how to tell karma the new files ?
var path = require('path');
module.exports = {
  'preprocessor:fis': ['factory', fisPreprocesor]
};

function fisPreprocesor(emitter, fileList, files, logger){
  emitter.on('file_list_modified', function(promise) {
    //it will only trigger when watch, not first time?
    console.log('xxx')
    promise.then(function(afiles) {
      console.log(afiles)
      return files;
    });
  });

  //use my tool to compile src to dist
  fis.complie(xxxx)

  files.splice(0, files.length);

  // add dist?
  files.unshift({
    pattern: 'dist/**/*.js',
    included: true,
    served: true,
    watched: false
  });
  return function(content, file, done) {
    // not need to change anything?
    console.log(file.path)
    done()
  }
}

fisPreprocesor.$inject = ['emitter', 'fileList', 'config.files', 'logger'];

update: maybe I can use frameworks plugin, run my tools, then update files.
trying...

HI, I had use framework plugin to compile and update files for karma.

but still left one problem, while auto watch, karma can't read the new file content, unless add monitor and refresh content & sha.

var path = require('path');
var shelljs = require('shelljs');
var crypto = require('crypto');
var logger;

module.exports = function(target){
  target['framework:fis'] = ['factory', fisFramework];
};

function fisFramework(files, config, emitter, loggerFactory){
  logger = loggerFactory.create('framework.fis');

  //wrap file with basePath
  if(config.fis.files) {
    config.fis.files.forEach(function (item) {
      files.push({
        pattern: path.join(config.basePath, item),
        included: true,
        served: true,
        watched: false
      });
    });
  }else{
    logger.warn('config.fis.files is null.')
  }

  //monitor file change
  emitter.on('file_list_modified', function(promise) {
    //compile
    var cmd = config.fis.cmd || 'larva karma -r ./src -d ./dist';
    logger.info(cmd);
    shelljs.exec(cmd);

    //update file sha, so karma can reload news
    promise.then(function(files) {
      files.served.forEach(function(item){
        item.content = require('fs').readFileSync(item.path).toString();
        item.sha = crypto.createHash('sha1').update(item.content).digest('hex');
      });
      return files;
    });
  });
}

fisFramework.$inject = ['config.files', 'config', 'emitter', 'logger'];

@atian25 Can you explain what does fis and what you want from karma.

Because you can do all work(processing) files using fis if it like grunt, and say karma where located processed files.

Or you can simple pass source files to karma and process it inside _karma_

'fis' or larva is our compile tools like grunt.
it will read all the source and compile them.

now I want to concat karma and fis work together.
and the code above is works.

my question is:

  • had I use the right way to update by using emitter and sha?

@atian25 Thanks.

  1. _grunt_ is not compile tool it's task runner.
  2. Modify file content using file_list_modified event is not best way.
  3. Why you don't modify file content in preprocessor function?

Can I look on larva?

yes, I use grunt for a long time, it is a task runner, but work with karma is usually as a compile tool.

larva is compile multi source, and not one src to one dist,
change any file will need to call larva release, then compile all.

so I don't know how to use preprocessor.

larva is a wrapper for fis which docs is Chinese.

https://github.com/ninegame/larva-cli

and showcase for karma and larva, may help:
https://github.com/atian25/angular-fis-showcase

@atian25 Can you add content for app.js in angular-fis-showcase and add test that checks this code.
Now I can not understand what you want process and how :(

will update tomorrow.
currently, there is a test case at src/test/test.spec.js which will compile to dist/public/test/test.spec.js and wrap with define

@maksimr updated.

some guide:

  1. view project with: npm run release and npm start , tmpdir is sth like C:\Users\TZ\AppData\Local\.larva-tmp\www
  2. run test with npm test, tmpDir is ./dist

I also expecting this.

Developing Plugins

The best way to understand how this works is to take a look at some of the existing plugins

existing plugins can be wrong, have existing bug, also possibly not utilize all functionality core karma offers.

Public Api

point from @atian25

  • seq
    I also need that, if it stand for sequence
  • concept
    clear, but i expecting deeper explanation

I like to suggest updating the documentation, especially FAQ and public API.

I hope when the documentation improved. Then when it did we got benefit that existing issues and bug are easier to tackle.

Hi guys, any clue on how to write an async framework factory?

'async' here is ambiguous, but I assume you mean a plugin that can block testing until a remote service responds with eg test data or service-availability signal. I don't think that is supported. The equivalent functionality can be achieved by starting remote services before invoking karma.

Please check @pact-foundation/karma-pact. You will understand what I’m talking about... they use “deasync” which is a lib that uses C++ under the hood just to block the thread so it can start a server... so you are basically saying that what they do there, it’s bad practice?

No, I did not say that. I said

The equivalent functionality can be achieved by starting remote services before invoking karma.

I just wanted to have a statement, because what they did on karma-pact, seems really bad practice. By saying that, I mean, we really need a better tutorial on how to write plugins for Karma... using a C++ extension only to stop the thread since karma doesn't support async for me is bad practice, and it's more or less "allowed" since karma doesn't have anything saying "this is good practice" X "this is bad practice"...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

IgorMinar picture IgorMinar  ·  5Comments

mboughaba picture mboughaba  ·  3Comments

HerrDerb picture HerrDerb  ·  5Comments

anius picture anius  ·  3Comments

TKTheTechie picture TKTheTechie  ·  4Comments