Skip to content

Instantly share code, notes, and snippets.

@yocontra
Created December 11, 2015 18:45
Show Gist options
  • Select an option

  • Save yocontra/9a323ae58d6da824f85f to your computer and use it in GitHub Desktop.

Select an option

Save yocontra/9a323ae58d6da824f85f to your computer and use it in GitHub Desktop.

Revisions

  1. contra created this gist Dec 11, 2015.
    78 changes: 78 additions & 0 deletions mock-rtc.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    'use strict';

    var mock = require('../temp-mock');
    var temasys = require('./index');
    var nu = require('new-operator');

    var RTCPeerConnectionMock = mock({
    methods: [
    'addIceCandidate',
    'addStream',
    'close',
    'createAnswer',
    'createDTMFSender',
    'createDataChannel',
    'createOffer',
    'setLocalDescription',
    'setRemoteDescription',
    'removeStream',
    'getLocalStreams',
    'getRemoteStreams',
    'getStats',
    'getStreamById',
    'updateIce'
    ],
    properties: [
    'iceConnectionState',
    'iceGatheringState',
    'localDescription',
    'remoteDescription',
    'onaddstream',
    'ondatachannel',
    'onicecandidate',
    'oniceconnectionstatechange',
    'onnegotiationneeded',
    'onremovestream',
    'onsignalingstatechange',
    'signalingState'
    ]
    });

    var RTCSessionDescriptionMock = mock({
    properties: [
    'type',
    'sdp'
    ]
    });

    var RTCIceCandidateMock = mock({
    properties: [
    'candidate',
    'sdpMid',
    'sdpMLineIndex'
    ]
    });

    module.exports = {
    RTCPeerConnection: function(){
    var inst = nu.apply(RTCPeerConnectionMock, arguments);
    temasys(function(rtc){
    mock.resolve(inst, rtc.RTCPeerConnection);
    });
    return inst;
    },
    RTCSessionDescription: function(){
    var inst = nu.apply(RTCSessionDescriptionMock, arguments);
    temasys(function(rtc){
    mock.resolve(inst, rtc.RTCSessionDescription);
    });
    return inst;
    },
    RTCIceCandidate: function(){
    var inst = nu.apply(RTCIceCandidateMock, arguments);
    temasys(function(rtc){
    mock.resolve(inst, rtc.RTCIceCandidate);
    });
    return inst;
    }
    };
    93 changes: 93 additions & 0 deletions temp-mock.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,93 @@
    'use strict';

    // temporarily mock a class
    // when the thing is loaded, replay all actions
    // that happened on the mock against the real thing

    function mockit(opt) {
    if (!opt) opt = {};
    if (!opt.properties) opt.properties = [];
    if (!opt.methods) opt.methods = [];

    function Mock(){
    this._ctorArgs = arguments;
    this._actions = [];
    this._state = {};
    this._opt = opt;
    }

    // TODO: detect key conflicts between these options
    opt.properties.forEach(hookProperty);
    opt.methods.forEach(hookMethod);
    return Mock;

    function hookMethod(k){
    Mock.prototype[k] = function(){
    this._actions.push({
    type: 'call',
    key: k,
    args: arguments
    });
    return this;
    };
    }

    function hookProperty(k){
    Object.defineProperty(Mock.prototype, k, {
    set: function(v){
    this._state[k] = v;
    if (this._actions) {
    this._actions.push({
    type: 'set',
    key: k,
    value: v
    });
    }
    },
    get: function(){
    return this._state[k];
    }
    });
    }
    }

    mockit.resolve = function(inst, fn) {
    // create the real thing
    var clazz = fn.apply(fn, inst._ctorArgs);
    if (typeof clazz === 'undefined') {
    clazz = {};
    }

    // replay all of our stuff onto the real thing
    inst._actions.forEach(function(action){
    if (action.type === 'set') {
    clazz[action.key] = action.value;
    } else if (action.type === 'call' &&
    typeof clazz[action.key] === 'function') {
    clazz[action.key].apply(inst, action.args);
    }
    });

    // make our fake thing into the real thing
    inst._opt.methods.forEach(function(k){
    inst[k] = clazz[k];
    });
    inst._opt.properties.forEach(function(k){
    Object.defineProperty(inst, k, {
    set: function(v) {
    return clazz[k] = v;
    },
    get: function(k) {
    return clazz[k];
    }
    });
    });

    delete inst._opt;
    delete inst._state;
    delete inst._actions;
    delete inst._ctorArgs;
    return clazz;
    };

    module.exports = mockit;