<commit_before>/*
 * Copyright 2015 Basho Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var rpb = require('../../../lib/protobuf/riakprotobuf');
var SecondaryIndexQuery = require('../../../lib/commands/kv/secondaryindexquery');
var RpbIndexResp = rpb.getProtoFor('RpbIndexResp');
var RpbIndexReq = rpb.getProtoFor('RpbIndexReq');
var RpbErrorResp = rpb.getProtoFor('RpbErrorResp');
var RpbPair = rpb.getProtoFor('RpbPair');
var assert = require('assert');

describe('SecondaryIndexQuery', function() {
    describe('Build', function() {
        it('should build a RpbIndexReq correctly for a single key query', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('email_bin')
                    .withIndexKey('roach@basho.com')
                    .withCallback(function(){})
                    .withTimeout(20000)
                    .withReturnKeyAndIndex(true)
                    .withMaxResults(20)
                    .withContinuation(new Buffer('1234'))
                    .build();

            var protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getType().toString('utf8'), 'default');
            assert.equal(protobuf.getBucket().toString('utf8'), 'MyBucket');
            // We should always be streaming from Riak
            assert.equal(protobuf.stream, true);
            assert.equal(protobuf.timeout, 20000);
            assert.equal(protobuf.getKey().toString('utf8'), 'roach@basho.com');
            assert.equal(protobuf.getRangeMin(), null);
            assert.equal(protobuf.getRangeMax(), null);
            assert.equal(protobuf.getIndex().toString('utf8'), 'email_bin');
            assert.equal(protobuf.getReturnTerms(), true);
            assert.equal(protobuf.getContinuation().toString('utf8'), '1234');
            assert.equal(protobuf.getQtype(), RpbIndexReq.IndexQueryType.eq);
            assert.equal(protobuf.getMaxResults(), 20);
            done();

        });

        it('should build a RpbIndexReq correctly for a range query', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withRange(0,50)
                    .withCallback(function(){})
                    .withTimeout(20000)
                    .withReturnKeyAndIndex(true)
                    .withMaxResults(20)
                    .withContinuation(new Buffer('1234'))
                    .build();

            var protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getType().toString('utf8'), 'default');
            assert.equal(protobuf.getBucket().toString('utf8'), 'MyBucket');
            // We should always be streaming from Riak
            assert.equal(protobuf.stream, true);
            assert.equal(protobuf.timeout, 20000);
            assert.equal(protobuf.getIndex().toString('utf8'), 'id_int');
            assert.equal(protobuf.getReturnTerms(), true);
            assert.equal(protobuf.getContinuation().toString('utf8'), '1234');
            assert.equal(protobuf.getQtype(), RpbIndexReq.IndexQueryType.range);
            assert.equal(protobuf.getKey(), null);
            // Riak's API expects strings, not numbers, for _int index queries
            // The command converts them
            assert.equal(protobuf.getRangeMin().toString('utf8'), '0');
            assert.equal(protobuf.getRangeMax().toString('utf8'), '50');
            done();
        });

        it('maxResults should override paginationSort', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withRange(0,50)
                    .withCallback(function(){})
                    .withMaxResults(20)
                    .withPaginationSort(true)
                    .build();

            var protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getPaginationSort(), null);

            siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withRange(0,50)
                    .withCallback(function(){})
                    .withPaginationSort(true)
                    .build();

            protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getPaginationSort(), true);
            done();

        });

        it('requires either an indexKey or rangeStart + rangeEnd', function(done) {

           assert.throws(
                function() { var siq = new SecondaryIndexQuery.Builder()
                            .withBucket('MyBucket')
                            .withIndexName('id_int')
                            .withCallback(function(){})
                            .build();
                },
                'either \'indxKey\' or \'rangeStart\' + \'rangeEnd\' are required'
            );
            done();

        });

        it('indexKey overrides range if both supplied', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withIndexKey(5)
                    .withRange(0,50)
                    .withCallback(function(){})
                    .build();

            var protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getKey().toString('utf8'), '5');
            assert.equal(protobuf.getRangeMin(), null);
            assert.equal(protobuf.getRangeMax(), null);
            assert.equal(protobuf.getQtype(), RpbIndexReq.IndexQueryType.eq);
            done();

        });

        it('should take multiple RpbIndexResp with just object keys and call the users callback with the response', function(done) {

            var callback = function(err, response) {

                assert.equal(response.values.length, 100);
                assert.equal(response.values[0].indexKey, null);
                assert.equal(response.values[0].objectKey, 'object_key');
                assert.equal(response.done, true);
                assert.equal(response.continuation.toString('utf8'), '1234');
                done();
            };

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_bin')
                    .withCallback(callback)
                    .withStreaming(false)
                    .withRange(0,50)
                    .build();

            for (var i = 0; i < 20; i++) {
                var indexResp = new RpbIndexResp();
                for (var j = 0; j < 5; j++) {
                    indexResp.keys.push(new Buffer('object_key'));
                }
                if (i === 19) {
                    indexResp.done = true;
                    indexResp.continuation = new Buffer('1234');
                }
                siq.onSuccess(indexResp);
            }
        });

        it('should take multiple RpbIndexResp with term/key pairs and call the users callback with the response', function(done) {

            var callback = function(err, response) {

                assert.equal(response.values.length, 100);
                assert.equal(response.values[0].indexKey, 'index_key');
                assert.equal(response.values[0].objectKey, 'object_key');
                assert.equal(response.done, true);
                assert.equal(response.continuation.toString('utf8'), '1234');
                done();
            };

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_bin')
                    .withCallback(callback)
                    .withStreaming(false)
                    .withReturnKeyAndIndex(true)
                    .withRange(0, 50)
                    .build();

            for (var i = 0; i < 20; i++) {
                var indexResp = new RpbIndexResp();
                for (var j = 0; j < 5; j++) {
                    var pair = new RpbPair();
                    pair.key = new Buffer('index_key');
                    pair.value = new Buffer('object_key');
                    indexResp.results.push(pair);
                }
                if (i === 19) {
                    indexResp.done = true;
                    indexResp.continuation = new Buffer('1234');
                }
                siq.onSuccess(indexResp);
            }
        });

        it('should take multiple RpbIndexResp with just object keys and stream the response', function(done) {

            var count = 0;
            var timesCalled = 0;
            var callback = function(err, response) {

                timesCalled++;
                count += response.values.length;

                assert.equal(response.values[0].indexKey, null);
                assert.equal(response.values[0].objectKey, 'object_key');

                if (response.done) {
                    assert.equal(timesCalled, 20);
                    assert.equal(count, 100);
                    assert.equal(response.continuation.toString('utf8'), '1234');
                    done();
                }
            };

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withCallback(callback)
                    .withStreaming(true)
                    .withRange(0, 50)
                    .build();

            for (var i = 0; i < 20; i++) {
                var indexResp = new RpbIndexResp();
                for (var j = 0; j < 5; j++) {
                    indexResp.keys.push(new Buffer('object_key'));
                }
                if (i === 19) {
                    indexResp.done = true;
                    indexResp.continuation = new Buffer('1234');
                }
                siq.onSuccess(indexResp);
            }
        });

        it('should take multiple RpbIndexResp with term/key pairs and stream the response', function(done) {

            var count = 0;
            var timesCalled = 0;
            var callback = function(err, response) {
                timesCalled++;
                count += response.values.length;

                assert.equal(response.values[0].indexKey, 123);
                assert.equal(response.values[0].objectKey, 'object_key');

                if (response.done) {
                    assert.equal(timesCalled, 20);
                    assert.equal(count, 100);
                    assert.equal(response.continuation.toString('utf8'), '1234');
                    done();
                }
            };

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withCallback(callback)
                    .withStreaming(true)
                    .withReturnKeyAndIndex(true)
                    .withRange(0, 50)
                    .build();

            for (var i = 0; i < 20; i++) {
                var indexResp = new RpbIndexResp();
                for (var j = 0; j < 5; j++) {
                    var pair = new RpbPair();
                    pair.key = new Buffer('123');
                    pair.value = new Buffer('object_key');
                    indexResp.results.push(pair);
                }
                if (i === 19) {
                    indexResp.done = true;
                    indexResp.continuation = new Buffer('1234');
                }
                siq.onSuccess(indexResp);
            }
        });

        it ('should take a RpbErrorResp and call the users callback with the error message', function(done) {
           var rpbErrorResp = new RpbErrorResp();
           rpbErrorResp.setErrmsg(new Buffer('this is an error'));

           var callback = function(err, response) {
               if (err) {
                   assert.equal(err,'this is an error');
                   done();
               }
           };

           var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_bin')
                    .withCallback(callback)
                    .withStreaming(false)
                    .withReturnKeyAndIndex(true)
                    .withRange(0,50)
                    .build();

            siq.onRiakError(rpbErrorResp);

       });

    });
});

<commit_msg>failing test  for https://github.com/basho/riak-nodejs-client/issues/80<commit_after>/*
 * Copyright 2015 Basho Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var rpb = require('../../../lib/protobuf/riakprotobuf');
var SecondaryIndexQuery = require('../../../lib/commands/kv/secondaryindexquery');
var RpbIndexResp = rpb.getProtoFor('RpbIndexResp');
var RpbIndexReq = rpb.getProtoFor('RpbIndexReq');
var RpbErrorResp = rpb.getProtoFor('RpbErrorResp');
var RpbPair = rpb.getProtoFor('RpbPair');
var assert = require('assert');

describe('SecondaryIndexQuery', function() {
    describe('Build', function() {
        it('should build a RpbIndexReq correctly for a single key query', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('email_bin')
                    .withIndexKey('roach@basho.com')
                    .withCallback(function(){})
                    .withTimeout(20000)
                    .withReturnKeyAndIndex(true)
                    .withMaxResults(20)
                    .withContinuation(new Buffer('1234'))
                    .build();

            var protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getType().toString('utf8'), 'default');
            assert.equal(protobuf.getBucket().toString('utf8'), 'MyBucket');
            // We should always be streaming from Riak
            assert.equal(protobuf.stream, true);
            assert.equal(protobuf.timeout, 20000);
            assert.equal(protobuf.getKey().toString('utf8'), 'roach@basho.com');
            assert.equal(protobuf.getRangeMin(), null);
            assert.equal(protobuf.getRangeMax(), null);
            assert.equal(protobuf.getIndex().toString('utf8'), 'email_bin');
            assert.equal(protobuf.getReturnTerms(), true);
            assert.equal(protobuf.getContinuation().toString('utf8'), '1234');
            assert.equal(protobuf.getQtype(), RpbIndexReq.IndexQueryType.eq);
            assert.equal(protobuf.getMaxResults(), 20);
            done();

        });

        it('should build a RpbIndexReq correctly for a single _bin key query without string2int conversion', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                .withBucket('MyBucket')
                .withIndexName('test_bin')
                .withIndexKey('9999999999999999')
                .withCallback(function(){})
                .build();

            var protobuf = siq.constructPbRequest();
            assert.equal(protobuf.getKey().toString('utf8'), '9999999999999999');
            done();
        });

        it('should build a RpbIndexReq correctly for a range query', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withRange(0,50)
                    .withCallback(function(){})
                    .withTimeout(20000)
                    .withReturnKeyAndIndex(true)
                    .withMaxResults(20)
                    .withContinuation(new Buffer('1234'))
                    .build();

            var protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getType().toString('utf8'), 'default');
            assert.equal(protobuf.getBucket().toString('utf8'), 'MyBucket');
            // We should always be streaming from Riak
            assert.equal(protobuf.stream, true);
            assert.equal(protobuf.timeout, 20000);
            assert.equal(protobuf.getIndex().toString('utf8'), 'id_int');
            assert.equal(protobuf.getReturnTerms(), true);
            assert.equal(protobuf.getContinuation().toString('utf8'), '1234');
            assert.equal(protobuf.getQtype(), RpbIndexReq.IndexQueryType.range);
            assert.equal(protobuf.getKey(), null);
            // Riak's API expects strings, not numbers, for _int index queries
            // The command converts them
            assert.equal(protobuf.getRangeMin().toString('utf8'), '0');
            assert.equal(protobuf.getRangeMax().toString('utf8'), '50');
            done();
        });

        it('maxResults should override paginationSort', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withRange(0,50)
                    .withCallback(function(){})
                    .withMaxResults(20)
                    .withPaginationSort(true)
                    .build();

            var protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getPaginationSort(), null);

            siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withRange(0,50)
                    .withCallback(function(){})
                    .withPaginationSort(true)
                    .build();

            protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getPaginationSort(), true);
            done();

        });

        it('requires either an indexKey or rangeStart + rangeEnd', function(done) {

           assert.throws(
                function() { var siq = new SecondaryIndexQuery.Builder()
                            .withBucket('MyBucket')
                            .withIndexName('id_int')
                            .withCallback(function(){})
                            .build();
                },
                'either \'indxKey\' or \'rangeStart\' + \'rangeEnd\' are required'
            );
            done();

        });

        it('indexKey overrides range if both supplied', function(done) {

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withIndexKey(5)
                    .withRange(0,50)
                    .withCallback(function(){})
                    .build();

            var protobuf = siq.constructPbRequest();

            assert.equal(protobuf.getKey().toString('utf8'), '5');
            assert.equal(protobuf.getRangeMin(), null);
            assert.equal(protobuf.getRangeMax(), null);
            assert.equal(protobuf.getQtype(), RpbIndexReq.IndexQueryType.eq);
            done();

        });

        it('should take multiple RpbIndexResp with just object keys and call the users callback with the response', function(done) {

            var callback = function(err, response) {

                assert.equal(response.values.length, 100);
                assert.equal(response.values[0].indexKey, null);
                assert.equal(response.values[0].objectKey, 'object_key');
                assert.equal(response.done, true);
                assert.equal(response.continuation.toString('utf8'), '1234');
                done();
            };

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_bin')
                    .withCallback(callback)
                    .withStreaming(false)
                    .withRange(0,50)
                    .build();

            for (var i = 0; i < 20; i++) {
                var indexResp = new RpbIndexResp();
                for (var j = 0; j < 5; j++) {
                    indexResp.keys.push(new Buffer('object_key'));
                }
                if (i === 19) {
                    indexResp.done = true;
                    indexResp.continuation = new Buffer('1234');
                }
                siq.onSuccess(indexResp);
            }
        });

        it('should take multiple RpbIndexResp with term/key pairs and call the users callback with the response', function(done) {

            var callback = function(err, response) {

                assert.equal(response.values.length, 100);
                assert.equal(response.values[0].indexKey, 'index_key');
                assert.equal(response.values[0].objectKey, 'object_key');
                assert.equal(response.done, true);
                assert.equal(response.continuation.toString('utf8'), '1234');
                done();
            };

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_bin')
                    .withCallback(callback)
                    .withStreaming(false)
                    .withReturnKeyAndIndex(true)
                    .withRange(0, 50)
                    .build();

            for (var i = 0; i < 20; i++) {
                var indexResp = new RpbIndexResp();
                for (var j = 0; j < 5; j++) {
                    var pair = new RpbPair();
                    pair.key = new Buffer('index_key');
                    pair.value = new Buffer('object_key');
                    indexResp.results.push(pair);
                }
                if (i === 19) {
                    indexResp.done = true;
                    indexResp.continuation = new Buffer('1234');
                }
                siq.onSuccess(indexResp);
            }
        });

        it('should take multiple RpbIndexResp with just object keys and stream the response', function(done) {

            var count = 0;
            var timesCalled = 0;
            var callback = function(err, response) {

                timesCalled++;
                count += response.values.length;

                assert.equal(response.values[0].indexKey, null);
                assert.equal(response.values[0].objectKey, 'object_key');

                if (response.done) {
                    assert.equal(timesCalled, 20);
                    assert.equal(count, 100);
                    assert.equal(response.continuation.toString('utf8'), '1234');
                    done();
                }
            };

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withCallback(callback)
                    .withStreaming(true)
                    .withRange(0, 50)
                    .build();

            for (var i = 0; i < 20; i++) {
                var indexResp = new RpbIndexResp();
                for (var j = 0; j < 5; j++) {
                    indexResp.keys.push(new Buffer('object_key'));
                }
                if (i === 19) {
                    indexResp.done = true;
                    indexResp.continuation = new Buffer('1234');
                }
                siq.onSuccess(indexResp);
            }
        });

        it('should take multiple RpbIndexResp with term/key pairs and stream the response', function(done) {

            var count = 0;
            var timesCalled = 0;
            var callback = function(err, response) {
                timesCalled++;
                count += response.values.length;

                assert.equal(response.values[0].indexKey, 123);
                assert.equal(response.values[0].objectKey, 'object_key');

                if (response.done) {
                    assert.equal(timesCalled, 20);
                    assert.equal(count, 100);
                    assert.equal(response.continuation.toString('utf8'), '1234');
                    done();
                }
            };

            var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_int')
                    .withCallback(callback)
                    .withStreaming(true)
                    .withReturnKeyAndIndex(true)
                    .withRange(0, 50)
                    .build();

            for (var i = 0; i < 20; i++) {
                var indexResp = new RpbIndexResp();
                for (var j = 0; j < 5; j++) {
                    var pair = new RpbPair();
                    pair.key = new Buffer('123');
                    pair.value = new Buffer('object_key');
                    indexResp.results.push(pair);
                }
                if (i === 19) {
                    indexResp.done = true;
                    indexResp.continuation = new Buffer('1234');
                }
                siq.onSuccess(indexResp);
            }
        });

        it ('should take a RpbErrorResp and call the users callback with the error message', function(done) {
           var rpbErrorResp = new RpbErrorResp();
           rpbErrorResp.setErrmsg(new Buffer('this is an error'));

           var callback = function(err, response) {
               if (err) {
                   assert.equal(err,'this is an error');
                   done();
               }
           };

           var siq = new SecondaryIndexQuery.Builder()
                    .withBucket('MyBucket')
                    .withIndexName('id_bin')
                    .withCallback(callback)
                    .withStreaming(false)
                    .withReturnKeyAndIndex(true)
                    .withRange(0,50)
                    .build();

            siq.onRiakError(rpbErrorResp);

       });

    });
});

<|endoftext|>


<commit_before>import { mori } from 'datascript-mori';
import { statsShape } from '../constants';

const { assoc, find, get, last, map, toClj, toJs } = mori;

export function transformSummaryStats (input) {
  const shape = toClj(statsShape);

  let output = map((element) => {
    let keyToFind = get(element, 'label').toLowerCase();
    let foundValue = find(toClj(input), keyToFind);
    return assoc(element, 'text', last(foundValue).toString());
  }, shape);

  return toJs(output);
}
<commit_msg>Extract percentage formatter<commit_after>import { mori } from 'datascript-mori';
import { statsShape } from '../constants';

const { assoc, find, get, last, map, toClj, toJs } = mori;

export function transformSummaryStats (input) {
  const shape = toClj(statsShape);

  let output = map((element) => {
    let keyToFind = get(element, 'label').toLowerCase();
    let foundValue = find(toClj(input), keyToFind);
    return assoc(element, 'text', last(foundValue).toString());
  }, shape);

  return toJs(output);
}

export function formattedPercentage (val) {
  return val * 100 + '%';
}
<|endoftext|>


<commit_before>// Bing maps API: https://docs.microsoft.com/en-us/bingmaps/rest-services/

L.BingLayer = L.TileLayer.extend({
	options: {
		// imagerySet: https://docs.microsoft.com/en-us/bingmaps/rest-services/imagery/get-imagery-metadata#template-parameters
		// supported:
		// - Aerial, AerialWithLabels (Deprecated), AerialWithLabelsOnDemand
		// - Road (Deprecated), RoadOnDemand
		// - CanvasDark, CanvasLight, CanvasGray
		// not supported: Birdseye*, Streetside
		type: 'RoadOnDemand',

		// https://docs.microsoft.com/en-us/bingmaps/rest-services/common-parameters-and-types/supported-culture-codes
		culture: '',

		attribution: 'Bing',
		minZoom: 1,
		maxZoom: 21
		// Actual `maxZoom` value may be less, depending on imagery set / coverage area
		// - 19~20 for all 'Aerial*'
		// - 20 for 'Road' (Deprecated)
	},

	initialize: function (key, options) {
		L.Util.setOptions(this, options);

		this._key = key;
		this._url = null;
	},

	tile2quad: function (x, y, z) {
		var quad = '';
		for (var i = z; i > 0; i--) {
			var digit = 0;
			var mask = 1 << i - 1;
			if ((x & mask) !== 0) { digit += 1; }
			if ((y & mask) !== 0) { digit += 2; }
			quad = quad + digit;
		}
		return quad;
	},

	getTileUrl: function (coords) {
		var data = {
			subdomain: this._getSubdomain(coords),
			quadkey: this.tile2quad(coords.x, coords.y, this._getZoomForUrl()),
			culture: this.options.culture // compatibility for deprecated imagery sets ('Road' etc)
		};
		return L.Util.template(this._url, data);
	},

	loadMetadata: function () {
		if (this.metaRequested) { return; }
		this.metaRequested = true;
		var _this = this;
		var cbid = '_bing_metadata_' + L.Util.stamp(this);
		window[cbid] = function (meta) {
			window[cbid] = undefined;
			var e = document.getElementById(cbid);
			e.parentNode.removeChild(e);
			if (meta.errorDetails) {
				throw new Error(meta.errorDetails);
			}
			_this.initMetadata(meta);
		};
		var urlScheme = document.location.protocol === 'file:' ? 'http' :
			document.location.protocol.slice(0, -1);
		var url = urlScheme + '://dev.virtualearth.net/REST/v1/Imagery/Metadata/' + this.options.type;
		url += L.Util.getParamString({
			jsonp: cbid,
			UriScheme: urlScheme,
			include: 'ImageryProviders',
			key: this._key,
			culture: this.options.culture
		});
		var script = document.createElement('script');
		script.type = 'text/javascript';
		script.src = url;
		script.id = cbid;
		document.getElementsByTagName('head')[0].appendChild(script);
	},

	initMetadata: function (meta) {
		var r = meta.resourceSets[0].resources[0];
		if (!r.imageUrl) { throw new Error('imageUrl not found in response'); }
		if (r.imageUrlSubdomains) { this.options.subdomains = r.imageUrlSubdomains; }
		this._url = r.imageUrl;
		this._providers = [];
		if (r.imageryProviders) {
			for (var i = 0; i < r.imageryProviders.length; i++) {
				var p = r.imageryProviders[i];
				for (var j = 0; j < p.coverageAreas.length; j++) {
					var c = p.coverageAreas[j];
					var coverage = {zoomMin: c.zoomMin, zoomMax: c.zoomMax, active: false};
					var bounds = L.latLngBounds(
							[c.bbox[0]+0.01, c.bbox[1]+0.01],
							[c.bbox[2]-0.01, c.bbox[3]-0.01]
					);
					coverage.bounds = bounds;
					coverage.attrib = p.attribution;
					this._providers.push(coverage);
				}
			}
		}
		this._update();
	},

	_update: function (center) {
		if (!this._url || !this._map) { return; }
		this._update_attribution();
		L.GridLayer.prototype._update.call(this, center);
	},

	_update_attribution: function () {
		var bounds = this._map.getBounds();
		bounds = L.latLngBounds(bounds.getSouthWest().wrap(), bounds.getNorthEast().wrap());
		var zoom = this._getZoomForUrl();
		for (var i = 0; i < this._providers.length; i++) {
			var p = this._providers[i];
			if ((zoom <= p.zoomMax && zoom >= p.zoomMin) &&
					bounds.intersects(p.bounds)) {
				if (!p.active && this._map.attributionControl)
					this._map.attributionControl.addAttribution(p.attrib);
				p.active = true;
			} else {
				if (p.active && this._map.attributionControl)
					this._map.attributionControl.removeAttribution(p.attrib);
				p.active = false;
			}
		}
	},

	onAdd: function (map) {
		// Note: Metadata could be loaded earlier, on layer initialize,
		//       but according to docs even such request is billable:
		//       https://docs.microsoft.com/en-us/bingmaps/getting-started/bing-maps-dev-center-help/understanding-bing-maps-transactions#rest-services
		//       That's why it's important to defer it till BingLayer is actually added to map
		this.loadMetadata();
		L.GridLayer.prototype.onAdd.call(this, map);
	},

	onRemove: function (map) {
		for (var i = 0; i < this._providers.length; i++) {
			var p = this._providers[i];
			if (p.active && this._map.attributionControl) {
				this._map.attributionControl.removeAttribution(p.attrib);
				p.active = false;
			}
		}
		L.GridLayer.prototype.onRemove.call(this, map);
	}
});

L.bingLayer = function (key, options) {
	return new L.BingLayer(key, options);
};
<commit_msg>L.BingLayer: constructor: `key` can be omitted if included in `options`<commit_after>// Bing maps API: https://docs.microsoft.com/en-us/bingmaps/rest-services/

L.BingLayer = L.TileLayer.extend({
	options: {
		// imagerySet: https://docs.microsoft.com/en-us/bingmaps/rest-services/imagery/get-imagery-metadata#template-parameters
		// supported:
		// - Aerial, AerialWithLabels (Deprecated), AerialWithLabelsOnDemand
		// - Road (Deprecated), RoadOnDemand
		// - CanvasDark, CanvasLight, CanvasGray
		// not supported: Birdseye*, Streetside
		type: 'RoadOnDemand',

		// https://docs.microsoft.com/en-us/bingmaps/rest-services/common-parameters-and-types/supported-culture-codes
		culture: '',

		attribution: 'Bing',
		minZoom: 1,
		maxZoom: 21
		// Actual `maxZoom` value may be less, depending on imagery set / coverage area
		// - 19~20 for all 'Aerial*'
		// - 20 for 'Road' (Deprecated)
	},

	initialize: function (key, options) {
		if (typeof key === 'object') {
			options = key;
			key = false;
		}
		L.Util.setOptions(this, options);

		if (key) { this.options.key = key; }
		this._url = null;
	},

	tile2quad: function (x, y, z) {
		var quad = '';
		for (var i = z; i > 0; i--) {
			var digit = 0;
			var mask = 1 << i - 1;
			if ((x & mask) !== 0) { digit += 1; }
			if ((y & mask) !== 0) { digit += 2; }
			quad = quad + digit;
		}
		return quad;
	},

	getTileUrl: function (coords) {
		var data = {
			subdomain: this._getSubdomain(coords),
			quadkey: this.tile2quad(coords.x, coords.y, this._getZoomForUrl()),
			culture: this.options.culture // compatibility for deprecated imagery sets ('Road' etc)
		};
		return L.Util.template(this._url, data);
	},

	loadMetadata: function () {
		if (this.metaRequested) { return; }
		this.metaRequested = true;
		var _this = this;
		var cbid = '_bing_metadata_' + L.Util.stamp(this);
		window[cbid] = function (meta) {
			window[cbid] = undefined;
			var e = document.getElementById(cbid);
			e.parentNode.removeChild(e);
			if (meta.errorDetails) {
				throw new Error(meta.errorDetails);
			}
			_this.initMetadata(meta);
		};
		var urlScheme = document.location.protocol === 'file:' ? 'http' :
			document.location.protocol.slice(0, -1);
		var url = urlScheme + '://dev.virtualearth.net/REST/v1/Imagery/Metadata/' + this.options.type;
		url += L.Util.getParamString({
			jsonp: cbid,
			UriScheme: urlScheme,
			include: 'ImageryProviders',
			key: this.options.key,
			culture: this.options.culture
		});
		var script = document.createElement('script');
		script.type = 'text/javascript';
		script.src = url;
		script.id = cbid;
		document.getElementsByTagName('head')[0].appendChild(script);
	},

	initMetadata: function (meta) {
		var r = meta.resourceSets[0].resources[0];
		if (!r.imageUrl) { throw new Error('imageUrl not found in response'); }
		if (r.imageUrlSubdomains) { this.options.subdomains = r.imageUrlSubdomains; }
		this._url = r.imageUrl;
		this._providers = [];
		if (r.imageryProviders) {
			for (var i = 0; i < r.imageryProviders.length; i++) {
				var p = r.imageryProviders[i];
				for (var j = 0; j < p.coverageAreas.length; j++) {
					var c = p.coverageAreas[j];
					var coverage = {zoomMin: c.zoomMin, zoomMax: c.zoomMax, active: false};
					var bounds = L.latLngBounds(
							[c.bbox[0]+0.01, c.bbox[1]+0.01],
							[c.bbox[2]-0.01, c.bbox[3]-0.01]
					);
					coverage.bounds = bounds;
					coverage.attrib = p.attribution;
					this._providers.push(coverage);
				}
			}
		}
		this._update();
	},

	_update: function (center) {
		if (!this._url || !this._map) { return; }
		this._update_attribution();
		L.GridLayer.prototype._update.call(this, center);
	},

	_update_attribution: function () {
		var bounds = this._map.getBounds();
		bounds = L.latLngBounds(bounds.getSouthWest().wrap(), bounds.getNorthEast().wrap());
		var zoom = this._getZoomForUrl();
		for (var i = 0; i < this._providers.length; i++) {
			var p = this._providers[i];
			if ((zoom <= p.zoomMax && zoom >= p.zoomMin) &&
					bounds.intersects(p.bounds)) {
				if (!p.active && this._map.attributionControl)
					this._map.attributionControl.addAttribution(p.attrib);
				p.active = true;
			} else {
				if (p.active && this._map.attributionControl)
					this._map.attributionControl.removeAttribution(p.attrib);
				p.active = false;
			}
		}
	},

	onAdd: function (map) {
		// Note: Metadata could be loaded earlier, on layer initialize,
		//       but according to docs even such request is billable:
		//       https://docs.microsoft.com/en-us/bingmaps/getting-started/bing-maps-dev-center-help/understanding-bing-maps-transactions#rest-services
		//       That's why it's important to defer it till BingLayer is actually added to map
		this.loadMetadata();
		L.GridLayer.prototype.onAdd.call(this, map);
	},

	onRemove: function (map) {
		for (var i = 0; i < this._providers.length; i++) {
			var p = this._providers[i];
			if (p.active && this._map.attributionControl) {
				this._map.attributionControl.removeAttribution(p.attrib);
				p.active = false;
			}
		}
		L.GridLayer.prototype.onRemove.call(this, map);
	}
});

L.bingLayer = function (key, options) {
	return new L.BingLayer(key, options);
};
<|endoftext|>


<commit_before>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Copyright (c) 2016, Joyent, Inc.
 */

/*
 * Integration tests for docker labels.
 */

var format = require('util').format;
var test = require('tape');
var vasync = require('vasync');

var cli = require('../lib/cli');
var common = require('../lib/common');
var vm = require('../lib/vm');

// --- Globals

var CLIENTS = {};
var CONTAINER_PREFIX = 'sdcdockertest_filters_';
var IMAGE_NAME = 'joyentunsupported/busybox_with_label_test';

// --- Tests

test('setup', function (tt) {

    tt.test('DockerEnv: alice init', cli.init);

    tt.test('vmapi client', vm.init);
});

function checkContainerFiltering(tt, args, expectedNames) {
    tt.test('container filtering', function (t) {
        cli.ps(t, {args: args}, function (err, containers) {
            t.ifErr(err, 'docker ps ' + args);
            t.equal(containers.length, expectedNames.length, 'Container count');
            var gotNames = containers.map(function (c) { return c.names; });
            t.deepEqual(gotNames.sort(), expectedNames.sort(),
                'Container names');
            t.end();
        });
    });
}

test('container filters', function (tt) {
    var containerName1 = common.makeContainerName(CONTAINER_PREFIX);
    var containerName2 = common.makeContainerName(CONTAINER_PREFIX);

    tt.test('create container 1', function (t) {
        var runArgs = format('-d --name %s --label fishing=true %s sleep 3600',
            containerName1, IMAGE_NAME);
        cli.run(t, {args: runArgs}, function (err, id) {
            t.ifErr(err, 'docker run ' + IMAGE_NAME);
            t.end();
        });
    });

    tt.test('create container 2', function (t) {
        var runArgs = format('-d --name %s --label fishing=fun %s sleep 3600',
            containerName2, IMAGE_NAME);
        cli.run(t, {args: runArgs}, function (err, id) {
            t.ifErr(err, 'docker run ' + IMAGE_NAME);
            t.end();
        });
    });

    // Filtering on the container label that comes from the image.
    checkContainerFiltering(tt, '--filter label=todd=cool',
        [containerName1, containerName2]);

    // Filtering on just the label name.
    checkContainerFiltering(tt, '--filter label=fishing',
        [containerName1, containerName2]);

    // Filtering on just the label name and value, which exists.
    checkContainerFiltering(tt, '--filter label=fishing=fun', [containerName2]);

    // Filtering on just the label name and value, which doesn't exist.
    checkContainerFiltering(tt, '--filter label=fishing=notfun', []);

    // Filtering on the container name prefix.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX,
        [containerName1, containerName2]);

    // Filtering on the full container name.
    checkContainerFiltering(tt, '--filter name=' + containerName1,
        [containerName1]);

    // Filtering using multiple filters matching both containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --filter label=fishing'
        + ' --filter label=todd=cool',
        [containerName1, containerName2]);

    // Filtering using multiple filters matching just one container.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --filter label=fishing=fun'
        + ' --filter label=todd=cool',
        [containerName2]);

    tt.test('stop container 1', function (t) {
        cli.stop(t, {args: containerName1}, function (err) {
            t.ifErr(err, 'docker stop ' + containerName1);
            t.end();
        });
    });

    // Filtering against running/stopped containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX,
        [containerName2]);

    // Filtering against running/stopped containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --filter status=exited',
        [containerName1]);

    // Filtering against running/stopped containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --filter status=running',
        [containerName2]);

    // Filtering using limit - should match running/stopped containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --last 10',
        [containerName1, containerName2]);

    // Filtering using negative limit - should only match running containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --last -10',
        [containerName2]);
});

test('image filters', function (tt) {
    tt.test('filter on image label', function (t) {
        cli.images(t, {args: '--filter label=todd=cool'},
            function (err, images)
        {
            t.ifErr(err, 'docker images --filter');
            t.equal(images.length, 1, 'Check one image returned');
            t.equal(images[0].repository, IMAGE_NAME, 'Check image name');
            t.end();
        });
    });

    tt.test('filter on nonexistant image label', function (t) {
        cli.images(t, {args: '--filter label=todd=notcool'},
            function (err, images)
        {
            t.ifErr(err, 'docker images nonexistant --filter');
            t.deepEqual(images, []);
            t.end();
        });
    });
});

test('teardown', cli.rmAllCreated);
<commit_msg>DOCKER-1007 sdc-docker cli-filters.test.js tests failing with uknown '--last' argument<commit_after>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Copyright (c) 2016, Joyent, Inc.
 */

/*
 * Integration tests for docker labels.
 */

var format = require('util').format;
var test = require('tape');
var vasync = require('vasync');

var cli = require('../lib/cli');
var common = require('../lib/common');
var vm = require('../lib/vm');

// --- Globals

var CLIENTS = {};
var CONTAINER_PREFIX = 'sdcdockertest_filters_';
var IMAGE_NAME = 'joyentunsupported/busybox_with_label_test';

// --- Tests

test('setup', function (tt) {

    tt.test('DockerEnv: alice init', cli.init);

    tt.test('vmapi client', vm.init);
});

function checkContainerFiltering(tt, args, expectedNames) {
    tt.test('container filtering', function (t) {
        cli.ps(t, {args: args}, function (err, containers) {
            t.ifErr(err, 'docker ps ' + args);
            t.equal(containers.length, expectedNames.length, 'Container count');
            var gotNames = containers.map(function (c) { return c.names; });
            t.deepEqual(gotNames.sort(), expectedNames.sort(),
                'Container names');
            t.end();
        });
    });
}

test('container filters', function (tt) {
    var containerName1 = common.makeContainerName(CONTAINER_PREFIX);
    var containerName2 = common.makeContainerName(CONTAINER_PREFIX);

    tt.test('create container 1', function (t) {
        var runArgs = format('-d --name %s --label fishing=true %s sleep 3600',
            containerName1, IMAGE_NAME);
        cli.run(t, {args: runArgs}, function (err, id) {
            t.ifErr(err, 'docker run ' + IMAGE_NAME);
            t.end();
        });
    });

    tt.test('create container 2', function (t) {
        var runArgs = format('-d --name %s --label fishing=fun %s sleep 3600',
            containerName2, IMAGE_NAME);
        cli.run(t, {args: runArgs}, function (err, id) {
            t.ifErr(err, 'docker run ' + IMAGE_NAME);
            t.end();
        });
    });

    // Filtering on the container label that comes from the image.
    checkContainerFiltering(tt, '--filter label=todd=cool',
        [containerName1, containerName2]);

    // Filtering on just the label name.
    checkContainerFiltering(tt, '--filter label=fishing',
        [containerName1, containerName2]);

    // Filtering on just the label name and value, which exists.
    checkContainerFiltering(tt, '--filter label=fishing=fun', [containerName2]);

    // Filtering on just the label name and value, which doesn't exist.
    checkContainerFiltering(tt, '--filter label=fishing=notfun', []);

    // Filtering on the container name prefix.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX,
        [containerName1, containerName2]);

    // Filtering on the full container name.
    checkContainerFiltering(tt, '--filter name=' + containerName1,
        [containerName1]);

    // Filtering using multiple filters matching both containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --filter label=fishing'
        + ' --filter label=todd=cool',
        [containerName1, containerName2]);

    // Filtering using multiple filters matching just one container.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --filter label=fishing=fun'
        + ' --filter label=todd=cool',
        [containerName2]);

    tt.test('stop container 1', function (t) {
        cli.stop(t, {args: containerName1}, function (err) {
            t.ifErr(err, 'docker stop ' + containerName1);
            t.end();
        });
    });

    // Filtering against running/stopped containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX,
        [containerName2]);

    // Filtering against running/stopped containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --filter status=exited',
        [containerName1]);

    // Filtering against running/stopped containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' --filter status=running',
        [containerName2]);

    // Filtering using limit - should match running/stopped containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' -n=10',
        [containerName1, containerName2]);

    // Filtering using negative limit - should only match running containers.
    checkContainerFiltering(tt, '--filter name=' + CONTAINER_PREFIX
        + ' -n=-10',
        [containerName2]);
});

test('image filters', function (tt) {
    tt.test('filter on image label', function (t) {
        cli.images(t, {args: '--filter label=todd=cool'},
            function (err, images)
        {
            t.ifErr(err, 'docker images --filter');
            t.equal(images.length, 1, 'Check one image returned');
            t.equal(images[0].repository, IMAGE_NAME, 'Check image name');
            t.end();
        });
    });

    tt.test('filter on nonexistant image label', function (t) {
        cli.images(t, {args: '--filter label=todd=notcool'},
            function (err, images)
        {
            t.ifErr(err, 'docker images nonexistant --filter');
            t.deepEqual(images, []);
            t.end();
        });
    });
});

test('teardown', cli.rmAllCreated);
<|endoftext|>


<commit_before>'use strict';

var get   = require('lodash.get');
var set   = require('lodash.set');
var unset = require('lodash.unset');

function VirtualFS() {
  this.files   = {};
  this.handles = {};
  this.next    = 0;
}

VirtualFS.prototype.open = function (path, flags, mode, callback) {
  if (typeof mode === 'function') {
    callback = mode;
    mode     = parseInt('666', 8);
  }

  var error = null;

  // TODO: Support all flags
  if (['r', 'w', 'wx'].indexOf(flags) === -1) {
    return callback(new Error('Unknown file open flag: ' + flags));
  }

  var file = get(this.files, path.split('/'), null);

  if (flags.indexOf('r') !== -1 && file === null) {
    error = new Error('ENOENT, open \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  if (flags.indexOf('x') !== -1 && file !== null) {
    error = new Error('EEXIST, open \'' + path + '\'');

    error.errno = 47;
    error.code  = 'EEXIST';
    error.path  = path;

    return callback(error);
  }

  if (flags.indexOf('w') !== -1 || (flags.indexOf('a') !== -1 && file === null)) {
    set(this.files, path.split('/'), new Buffer(0));
  }

  var fd = this.next++;

  this.handles[fd] = path;

  return callback(null, fd);
};

VirtualFS.prototype.stat = function (path, callback) {
  var file = get(this.files, path.split('/'), null);

  if (file === null) {
    var error = new Error('ENOENT, stat \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  var now = Date.now();

  // TODO: Return a fs.Stats instance
  var stats = {
    mode:  '666',
    uid:   0,
    gid:   0,
    size:  Buffer.isBuffer(file) ? file.length : 0,
    atime: now,
    mtime: now
  };

  return callback(null, stats);
};

VirtualFS.prototype.read = function (fd, buffer, offset, length, position, callback) {
  if (typeof this.handles[fd] !== 'string') {
    var error = new Error('EBADF, read');

    error.errno = 9;
    error.code  = 'EBADF';

    return callback(error);
  }

  var path = this.handles[fd];
  var file = get(this.files, path.split('/'), null);

  if (offset > file.length) {
    return callback(null, 0, null);
  }

  var bytesRead = Math.min(file.length - offset, length);

  file.copy(buffer, 0, offset, bytesRead);

  return callback(null, bytesRead, buffer);
};

VirtualFS.prototype.write = function (fd, buffer, offset, length, position, callback) {
  if (typeof this.handles[fd] !== 'string') {
    var error = new Error('EBADF, read');

    error.errno = 9;
    error.code  = 'EBADF';

    return callback(error);
  }

  var path = this.handles[fd];
  var file = get(this.files, path.split('/'), null);

  var newFile = new Buffer(Math.max(file.length, offset + buffer.length));

  file.copy(newFile);
  buffer.copy(newFile, offset);

  set(this.files, path.split('/'), newFile);

  return callback(null, buffer.length, buffer);
};

VirtualFS.prototype.mkdir = function (path, mode, callback) {
  var error = null;
  var file  = get(this.files, path.split('/'), null);

  if (typeof mode === 'function') {
    callback = mode;
    mode     = null;
  }

  mode = mode || parseInt('666', 8);

  if (file !== null) {
    error = new Error('EEXIST, mkdir \'' + path + '\'');

    error.errno = 47;
    error.code  = 'EEXIST';
    error.path  = path;

    return callback(error);
  }

  set(this.files, path.split('/'), {'.': {mode: mode}});

  return callback(null);
};

VirtualFS.prototype.readdir = function (path, callback) {
  var error = null;
  var file  = get(this.files, path.split('/'), null);

  if (file === null) {
    error = new Error('ENOENT, readdir \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  if (Buffer.isBuffer(file)) {
    error = new Error('ENOTDIR,, readdir \'' + path + '\'');

    error.errno = 27;
    error.code  = 'ENOTDIR,';
    error.path  = path;

    return callback(error);
  }

  return callback(null, Object.keys(file));
};

VirtualFS.prototype.rmdir = function (path, callback) {
  var error = null;
  var file  = get(this.files, path.split('/'), null);

  if (file === null) {
    error = new Error('ENOENT, rmdir \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  if (Buffer.isBuffer(file)) {
    error = new Error('ENOTDIR, rmdir \'' + path + '\'');

    error.errno = 27;
    error.code  = 'ENOTDIR';
    error.path  = path;

    return callback(error);
  }

  unset(this.files, path.split('/'));

  return callback(null);
};

VirtualFS.prototype.unlink = function (path, callback) {
  var error = null;
  var file  = get(this.files, path.split('/'), null);

  if (file === null) {
    error = new Error('ENOENT, unlink \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  if (!Buffer.isBuffer(file)) {
    error = new Error('EISDIR, unlink \'' + path + '\'');

    error.errno = 28;
    error.code  = 'EISDIR';
    error.path  = path;

    return callback(error);
  }

  unset(this.files, path.split('/'));

  return callback(null);
};

VirtualFS.prototype.close = function (fd, callback) {
  if (typeof this.handles[fd] !== 'string') {
    var error = new Error('EBADF, close');

    error.errno = 9;
    error.code  = 'EBADF';

    return callback(error);
  }

  delete this.handles[fd];

  return callback(null);
};

VirtualFS.prototype.get = function (path) {
  return get(this.files, path.split('/'), null);
};

VirtualFS.prototype.set = function (path, file) {
  return set(this.files, path.split('/'), file);
};

module.exports = VirtualFS;
<commit_msg>Add writeFile, readFile and rename to VirtualFS<commit_after>'use strict';

var get   = require('lodash.get');
var set   = require('lodash.set');
var unset = require('lodash.unset');

function VirtualFS() {
  this.files   = {};
  this.handles = {};
  this.next    = 0;
}

VirtualFS.prototype.open = function (path, flags, mode, callback) {
  if (typeof mode === 'function') {
    callback = mode;
    mode     = parseInt('666', 8);
  }

  var error = null;

  // TODO: Support all flags
  if (['r', 'w', 'wx'].indexOf(flags) === -1) {
    return callback(new Error('Unknown file open flag: ' + flags));
  }

  var file = get(this.files, path.split('/'), null);

  if (flags.indexOf('r') !== -1 && file === null) {
    error = new Error('ENOENT, open \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  if (flags.indexOf('x') !== -1 && file !== null) {
    error = new Error('EEXIST, open \'' + path + '\'');

    error.errno = 47;
    error.code  = 'EEXIST';
    error.path  = path;

    return callback(error);
  }

  if (flags.indexOf('w') !== -1 || (flags.indexOf('a') !== -1 && file === null)) {
    set(this.files, path.split('/'), new Buffer(0));
  }

  var fd = this.next++;

  this.handles[fd] = path;

  return callback(null, fd);
};

VirtualFS.prototype.stat = function (path, callback) {
  var file = get(this.files, path.split('/'), null);

  if (file === null) {
    var error = new Error('ENOENT, stat \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  var now = Date.now();

  // TODO: Return a fs.Stats instance
  var stats = {
    mode:  '666',
    uid:   0,
    gid:   0,
    size:  Buffer.isBuffer(file) ? file.length : 0,
    atime: now,
    mtime: now
  };

  return callback(null, stats);
};

VirtualFS.prototype.read = function (fd, buffer, offset, length, position, callback) {
  if (typeof this.handles[fd] !== 'string') {
    var error = new Error('EBADF, read');

    error.errno = 9;
    error.code  = 'EBADF';

    return callback(error);
  }

  var path = this.handles[fd];
  var file = get(this.files, path.split('/'), null);

  if (offset > file.length) {
    return callback(null, 0, null);
  }

  var bytesRead = Math.min(file.length - offset, length);

  file.copy(buffer, 0, offset, bytesRead);

  return callback(null, bytesRead, buffer);
};

VirtualFS.prototype.write = function (fd, buffer, offset, length, position, callback) {
  if (typeof this.handles[fd] !== 'string') {
    var error = new Error('EBADF, read');

    error.errno = 9;
    error.code  = 'EBADF';

    return callback(error);
  }

  var path = this.handles[fd];
  var file = get(this.files, path.split('/'), null);

  var newFile = new Buffer(Math.max(file.length, offset + buffer.length));

  file.copy(newFile);
  buffer.copy(newFile, offset);

  set(this.files, path.split('/'), newFile);

  return callback(null, buffer.length, buffer);
};

VirtualFS.prototype.mkdir = function (path, mode, callback) {
  var error = null;
  var file  = get(this.files, path.split('/'), null);

  if (typeof mode === 'function') {
    callback = mode;
    mode     = null;
  }

  mode = mode || parseInt('666', 8);

  if (file !== null) {
    error = new Error('EEXIST, mkdir \'' + path + '\'');

    error.errno = 47;
    error.code  = 'EEXIST';
    error.path  = path;

    return callback(error);
  }

  set(this.files, path.split('/'), {'.': {mode: mode}});

  return callback(null);
};

VirtualFS.prototype.readdir = function (path, callback) {
  var error = null;
  var file  = get(this.files, path.split('/'), null);

  if (file === null) {
    error = new Error('ENOENT, readdir \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  if (Buffer.isBuffer(file)) {
    error = new Error('ENOTDIR,, readdir \'' + path + '\'');

    error.errno = 27;
    error.code  = 'ENOTDIR,';
    error.path  = path;

    return callback(error);
  }

  return callback(null, Object.keys(file));
};

VirtualFS.prototype.rmdir = function (path, callback) {
  var error = null;
  var file  = get(this.files, path.split('/'), null);

  if (file === null) {
    error = new Error('ENOENT, rmdir \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  if (Buffer.isBuffer(file)) {
    error = new Error('ENOTDIR, rmdir \'' + path + '\'');

    error.errno = 27;
    error.code  = 'ENOTDIR';
    error.path  = path;

    return callback(error);
  }

  unset(this.files, path.split('/'));

  return callback(null);
};

VirtualFS.prototype.unlink = function (path, callback) {
  var error = null;
  var file  = get(this.files, path.split('/'), null);

  if (file === null) {
    error = new Error('ENOENT, unlink \'' + path + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = path;

    return callback(error);
  }

  if (!Buffer.isBuffer(file)) {
    error = new Error('EISDIR, unlink \'' + path + '\'');

    error.errno = 28;
    error.code  = 'EISDIR';
    error.path  = path;

    return callback(error);
  }

  unset(this.files, path.split('/'));

  return callback(null);
};

VirtualFS.prototype.close = function (fd, callback) {
  if (typeof this.handles[fd] !== 'string') {
    var error = new Error('EBADF, close');

    error.errno = 9;
    error.code  = 'EBADF';

    return callback(error);
  }

  delete this.handles[fd];

  return callback(null);
};

VirtualFS.prototype.writeFile = function(filename, data, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options  = {};
  }

  if (!Buffer.isBuffer(data)) {
    data = new Buffer(data.toString(), options.encoding || 'utf8');
  }

  // TODO: Support options.flag and options.mode

  set(this.files, filename.split('/'), data);

  return callback(null);
};

VirtualFS.prototype.readFile = function(filename, options, callback) {
  if (typeof options === 'function') {
    callback = options;
    options  = {};
  }

  var file = get(this.files, filename.split('/'), null);

  if (file === null) {
    error = new Error('ENOENT, open \'' + filename + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = filename;

    return callback(error);
  }

  return callback(null, options.hasOwnProperty('encoding') ? file.toString(options.encoding) : file);
};

VirtualFS.prototype.rename = function(oldPath, newPath, callback) {
  var file = get(this.files, oldPath.split('/'), null);

  if (file === null) {
    error = new Error('ENOENT, open \'' + oldPath + '\'');

    error.errno = 34;
    error.code  = 'ENOENT';
    error.path  = oldPath;

    return callback(error);
  }

  if (get(this.files, newPath.split('/'), null) !== null) {
    error = new Error('EEXIST, open \'' + newPath + '\'');

    error.errno = 47;
    error.code  = 'EEXIST';
    error.path  = newPath;

    return callback(error);
  }

  set(this.files, newPath.split('/'), file);

  unset(this.files, oldPath.split('/'));

  return callback(null);
};

VirtualFS.prototype.get = function (path) {
  return get(this.files, path.split('/'), null);
};

VirtualFS.prototype.set = function (path, file) {
  return set(this.files, path.split('/'), file);
};

module.exports = VirtualFS;
<|endoftext|>


<commit_before>/* Copyright (c) 2014 Luca Lanziani, MIT License */
"use strict";

var util = require('util');

var _     = require('underscore');
var Stomp = require('stomp-client');

module.exports = function( options ) {
  var seneca = this;
  var plugin = 'stomp-transport';

  var so = seneca.options();

  var ACT_CHANNEL = "/queue/%s_act";
  var RES_CHANNEL = "/queue/%s_res";

  options = seneca.util.deepextend(
    {
      stomp: {
        timeout:     so.timeout ? so.timeout-555 :  22222,
        type:        'stomp',
        host:        'localhost',
        port:        61613,
        act_channel: ACT_CHANNEL,
        res_channel: RES_CHANNEL
      },
    },
    so.transport,
    options);

  var tu = seneca.export('transport/utils');

  seneca.add({role:'transport', hook:'listen', type:'stomp'}, hook_listen_stomp);
  seneca.add({role:'transport', hook:'client', type:'stomp'}, hook_client_stomp);

  function hook_listen_stomp(args, done) {
    var seneca         = this;
    var type           = args.type;
    var listen_options = seneca.util.clean(_.extend({}, options[type], args));

    function listen_topic(topic) {
      var channel_in = util.format(listen_options.act_channel, topic);
      var channel_out = util.format(listen_options.res_channel, topic);

      var stomp_in  = make_stomp_client(listen_options, 'listen_in');
      var stomp_out = make_stomp_client(listen_options, 'listen_out');

      stomp_in.on('connect', function () {
        seneca.log.info('listen', 'connected', channel_in, seneca);
        stomp_in.subscribe(channel_in, function (msgstr, headers) {
          var data = tu.parseJSON(seneca, 'listen-'+type, msgstr);

          tu.handle_request(seneca, data, listen_options, function (out) {
            if (null === out) return;
            var outstr = tu.stringifyJSON(seneca, 'listen-'+type, out);
            stomp_out.publish(channel_out, outstr);
          });
        });
      });

      stomp_out.on('connect', function () {
        seneca.log.debug('listen', 'connect', 'out', topic, seneca);
        stomp_in.connect();
      });

      stomp_out.connect();

    }

    tu.listen_topics( seneca, args, listen_options, function(topic) {
      listen_topic(topic);
    });

    seneca.log.info('listen', 'open', listen_options, seneca);

    done();
  }

  function hook_client_stomp(args, clientdone) {
    var seneca         = this;
    var type           = args.type;
    var client_options = seneca.util.clean(_.extend({}, options[type], args));

    tu.make_client(make_send, client_options, clientdone);

    function make_send(spec, topic, send_done) {
      var channel_in = util.format(client_options.res_channel, topic);
      var channel_out = util.format(client_options.act_channel, topic);

      var stomp_in  = make_stomp_client(client_options, 'client_in');
      var stomp_out = make_stomp_client(client_options, 'client_out');

      stomp_in.on('connect', function (session_id) {
        seneca.log.debug('client', 'connected', channel_in, client_options, seneca);

        stomp_in.subscribe(channel_in, function (msgstr) {
          var input = tu.parseJSON(seneca, 'client-'+type, msgstr);
          seneca.log.info('client', 'input', input);
          tu.handle_response(seneca, input, client_options);
        });
      });

      stomp_out.on('connect', function (session_id) {

        send_done( null, function( args, done ) {
          var outmsg = tu.prepare_request(this, args, done);
          var outstr = tu.stringifyJSON(seneca, 'client-'+type, outmsg);

          stomp_out.publish(channel_out, outstr);
        });

      });

      stomp_out.connect();
      stomp_in.connect();

    }
  }

  function make_stomp_client(options, identifier) {
    var client = new Stomp(options.host, options.port);
    client.on('error', function (error) {
      seneca.log.error('transport', 'stomp', identifier, error.message);
    });

    seneca.add('role:seneca,cmd:close', function (close_args, done) {
      var closer = this;

      client.disconnect();
      closer.prior(close_args, done);
    });
    return client;
  }

  return {
    name: plugin,
  };
};
<commit_msg>Change logging from info level to debug<commit_after>/* Copyright (c) 2014 Luca Lanziani, MIT License */
"use strict";

var util = require('util');

var _     = require('underscore');
var Stomp = require('stomp-client');

module.exports = function( options ) {
  var seneca = this;
  var plugin = 'stomp-transport';

  var so = seneca.options();

  var ACT_CHANNEL = "/queue/%s_act";
  var RES_CHANNEL = "/queue/%s_res";

  options = seneca.util.deepextend(
    {
      stomp: {
        timeout:     so.timeout ? so.timeout-555 :  22222,
        type:        'stomp',
        host:        'localhost',
        port:        61613,
        act_channel: ACT_CHANNEL,
        res_channel: RES_CHANNEL
      },
    },
    so.transport,
    options);

  var tu = seneca.export('transport/utils');

  seneca.add({role:'transport', hook:'listen', type:'stomp'}, hook_listen_stomp);
  seneca.add({role:'transport', hook:'client', type:'stomp'}, hook_client_stomp);

  function hook_listen_stomp(args, done) {
    var seneca         = this;
    var type           = args.type;
    var listen_options = seneca.util.clean(_.extend({}, options[type], args));

    function listen_topic(topic) {
      var channel_in = util.format(listen_options.act_channel, topic);
      var channel_out = util.format(listen_options.res_channel, topic);

      var stomp_in  = make_stomp_client(listen_options, 'listen_in');
      var stomp_out = make_stomp_client(listen_options, 'listen_out');

      stomp_in.on('connect', function () {
        seneca.log.debug('listen', 'connected', channel_in, seneca);
        stomp_in.subscribe(channel_in, function (msgstr, headers) {
          var data = tu.parseJSON(seneca, 'listen-'+type, msgstr);

          tu.handle_request(seneca, data, listen_options, function (out) {
            if (null === out) return;
            var outstr = tu.stringifyJSON(seneca, 'listen-'+type, out);
            stomp_out.publish(channel_out, outstr);
          });
        });
      });

      stomp_out.on('connect', function () {
        seneca.log.debug('listen', 'connect', 'out', topic, seneca);
        stomp_in.connect();
      });

      stomp_out.connect();

    }

    tu.listen_topics( seneca, args, listen_options, function(topic) {
      listen_topic(topic);
    });

    seneca.log.debug('listen', 'open', listen_options, seneca);

    done();
  }

  function hook_client_stomp(args, clientdone) {
    var seneca         = this;
    var type           = args.type;
    var client_options = seneca.util.clean(_.extend({}, options[type], args));

    tu.make_client(make_send, client_options, clientdone);

    function make_send(spec, topic, send_done) {
      var channel_in = util.format(client_options.res_channel, topic);
      var channel_out = util.format(client_options.act_channel, topic);

      var stomp_in  = make_stomp_client(client_options, 'client_in');
      var stomp_out = make_stomp_client(client_options, 'client_out');

      stomp_in.on('connect', function (session_id) {
        seneca.log.debug('client', 'connected', channel_in, client_options, seneca);

        stomp_in.subscribe(channel_in, function (msgstr) {
          var input = tu.parseJSON(seneca, 'client-'+type, msgstr);
          seneca.log.debug('client', 'input', input);
          tu.handle_response(seneca, input, client_options);
        });
      });

      stomp_out.on('connect', function (session_id) {

        send_done( null, function( args, done ) {
          var outmsg = tu.prepare_request(this, args, done);
          var outstr = tu.stringifyJSON(seneca, 'client-'+type, outmsg);

          stomp_out.publish(channel_out, outstr);
        });

      });

      stomp_out.connect();
      stomp_in.connect();

    }
  }

  function make_stomp_client(options, identifier) {
    var client = new Stomp(options.host, options.port);
    client.on('error', function (error) {
      seneca.log.error('transport', 'stomp', identifier, error.message);
    });

    seneca.add('role:seneca,cmd:close', function (close_args, done) {
      var closer = this;

      client.disconnect();
      closer.prior(close_args, done);
    });
    return client;
  }

  return {
    name: plugin,
  };
};
<|endoftext|>


<commit_before>var github_actions = require('../../lib/services/github_actions')

describe('GitHub Actions CI Provider', function() {
  it('can detect GitHub Actions', function() {
    process.env.GITHUB_ACTIONS = '1'
    expect(github_actions.detect()).toBe(true)
  })

  it('can get GitHub Actions env info', function() {
    process.env.GITHUB_SHA = '743b04806ea677403aa2ff26c6bdeb85005de658'
    process.env.GITHUB_REPOSITORY = 'codecov/codecov-repo'
    process.env.GITHUB_REF = 'refs/heads/master'

    expect(github_actions.configuration()).toEqual({
      service: 'github_actions',
      commit: '743b04806ea677403aa2ff26c6bdeb85005de658',
      branch: 'master',
      slug: 'codecov/codecov-repo',
    })
  })
})
<commit_msg>correct service name<commit_after>var github_actions = require('../../lib/services/github_actions')

describe('GitHub Actions CI Provider', function() {
  it('can detect GitHub Actions', function() {
    process.env.GITHUB_ACTIONS = '1'
    expect(github_actions.detect()).toBe(true)
  })

  it('can get GitHub Actions env info', function() {
    process.env.GITHUB_SHA = '743b04806ea677403aa2ff26c6bdeb85005de658'
    process.env.GITHUB_REPOSITORY = 'codecov/codecov-repo'
    process.env.GITHUB_REF = 'refs/heads/master'

    expect(github_actions.configuration()).toEqual({
      service: 'github-actions',
      commit: '743b04806ea677403aa2ff26c6bdeb85005de658',
      branch: 'master',
      slug: 'codecov/codecov-repo',
    })
  })
})
<|endoftext|>


<commit_before>
describe("OnLocal/RemoteChange", function() {
    beforeEach(function() {
        jasmine.Ajax.install();
        // stub initial HTTP request
        jasmine.Ajax.stubRequest(window.location.href).andReturn(TestResponses.defaultInit.success);
    });

    afterEach(function() {
        this.puppet.unobserve();
        jasmine.Ajax.uninstall();
    });

    beforeEach(function() {
        jasmine.WebSocket.install();
    });
    afterEach(function() {
        jasmine.WebSocket.uninstall();
    });
    it("should call onLocalChange callback for outgoing patches", function(done) {
        var sentSpy = jasmine.createSpy("onLocalChange");

        var puppet = this.puppet = new Puppet({
            useWebSocket: true,
            onLocalChange: sentSpy
        });
        var websocket = jasmine.WebSocket.spy.calls.mostRecent().returnValue;
        //open WS for changes
        websocket.open();
        this.puppet.obj.hello = "onLocalChange callback";

        // wait for observer and mocked initial HTTP response
        setTimeout(function() {
            expect(puppet.obj.hello).toEqual("onLocalChange callback");
            expect(sentSpy.calls.mostRecent().args[0]).toEqual([{
                "op": "replace",
                "path": "/hello",
                "value": "onLocalChange callback"
            }]);
            done();
        }, 100); // for FF
    });

    it("should call onRemoteChange callback for applied patches", function(done) {
        var receivedSpy = jasmine.createSpy("onRemoteChange");

        var puppet = this.puppet = new Puppet({
            useWebSocket: true,
            onRemoteChange: receivedSpy
        });
        var websocket = jasmine.WebSocket.spy.calls.mostRecent().returnValue;
        //open WS for changes
        websocket.open();
        websocket.onmessage({
            data: '[{"op":"replace","path":"/hello","value":"onRemoteChange callback"}]'
        });

        // wait for observer and mocked initial HTTP response
        setTimeout(function() {
            expect(puppet.obj.hello).toEqual("onRemoteChange callback");
            var mostRecentCall = receivedSpy.calls.mostRecent();
            expect(mostRecentCall.args[0]).toEqual([{
                "op": "replace",
                "path": "/hello",
                "value": "onRemoteChange callback"
            }]);
            expect(mostRecentCall.args[1]).toEqual([{removed: 'world'}]);
            done();
        }, 100); // for FF
    });

    it("should fire patch-applied event for applied patches", function(done) {
        var receivedSpy = jasmine.createSpy("patch-applied");

        var puppet = this.puppet = new Puppet({
            useWebSocket: true
        });
        puppet.addEventListener('patch-applied', receivedSpy);
        var websocket = jasmine.WebSocket.spy.calls.mostRecent().returnValue;
        //open WS for changes
        websocket.open();
        websocket.onmessage({
            data: '[{"op":"replace","path":"/hello","value":"patch-applied"}]'
        });

        // wait for observer and mocked initial HTTP response
        setTimeout(function() {
            var detail = receivedSpy.calls.mostRecent().args[0].detail;
            expect(detail.patches).toEqual([{
                "op": "replace",
                "path": "/hello",
                "value": "patch-applied"
            }]);
            expect(detail.results).toEqual([{removed: 'world'}]);
            done();
        }, 100); // for FF
    });
});
<commit_msg>Fix test for simple return values of jsonpatch.apply<commit_after>
describe("OnLocal/RemoteChange", function() {
    beforeEach(function() {
        jasmine.Ajax.install();
        // stub initial HTTP request
        jasmine.Ajax.stubRequest(window.location.href).andReturn(TestResponses.defaultInit.success);
    });

    afterEach(function() {
        this.puppet.unobserve();
        jasmine.Ajax.uninstall();
    });

    beforeEach(function() {
        jasmine.WebSocket.install();
    });
    afterEach(function() {
        jasmine.WebSocket.uninstall();
    });
    it("should call onLocalChange callback for outgoing patches", function(done) {
        var sentSpy = jasmine.createSpy("onLocalChange");

        var puppet = this.puppet = new Puppet({
            useWebSocket: true,
            onLocalChange: sentSpy
        });
        var websocket = jasmine.WebSocket.spy.calls.mostRecent().returnValue;
        //open WS for changes
        websocket.open();
        this.puppet.obj.hello = "onLocalChange callback";

        // wait for observer and mocked initial HTTP response
        setTimeout(function() {
            expect(puppet.obj.hello).toEqual("onLocalChange callback");
            expect(sentSpy.calls.mostRecent().args[0]).toEqual([{
                "op": "replace",
                "path": "/hello",
                "value": "onLocalChange callback"
            }]);
            done();
        }, 100); // for FF
    });

    it("should call onRemoteChange callback for applied patches", function(done) {
        var receivedSpy = jasmine.createSpy("onRemoteChange");

        var puppet = this.puppet = new Puppet({
            useWebSocket: true,
            onRemoteChange: receivedSpy
        });
        var websocket = jasmine.WebSocket.spy.calls.mostRecent().returnValue;
        //open WS for changes
        websocket.open();
        websocket.onmessage({
            data: '[{"op":"replace","path":"/hello","value":"onRemoteChange callback"}]'
        });

        // wait for observer and mocked initial HTTP response
        setTimeout(function() {
            expect(puppet.obj.hello).toEqual("onRemoteChange callback");
            var mostRecentCall = receivedSpy.calls.mostRecent();
            expect(mostRecentCall.args[0]).toEqual([{
                "op": "replace",
                "path": "/hello",
                "value": "onRemoteChange callback"
            }]);
            expect(mostRecentCall.args[1]).toEqual(['world']);
            done();
        }, 100); // for FF
    });

    it("should fire patch-applied event for applied patches", function(done) {
        var receivedSpy = jasmine.createSpy("patch-applied");

        var puppet = this.puppet = new Puppet({
            useWebSocket: true
        });
        puppet.addEventListener('patch-applied', receivedSpy);
        var websocket = jasmine.WebSocket.spy.calls.mostRecent().returnValue;
        //open WS for changes
        websocket.open();
        websocket.onmessage({
            data: '[{"op":"replace","path":"/hello","value":"patch-applied"}]'
        });

        // wait for observer and mocked initial HTTP response
        setTimeout(function() {
            var detail = receivedSpy.calls.mostRecent().args[0].detail;
            expect(detail.patches).toEqual([{
                "op": "replace",
                "path": "/hello",
                "value": "patch-applied"
            }]);
            expect(detail.results).toEqual(['world']);
            done();
        }, 100); // for FF
    });
});
<|endoftext|>