From 5e29647897505cdcf79596e7303b5f97171297a3 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Thu, 28 Mar 2013 23:53:29 +0100 Subject: [PATCH 1/4] js: Remove redundant config not working on Node 0.10 --- js/Gruntfile.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/js/Gruntfile.js b/js/Gruntfile.js index f290250a..195decd6 100644 --- a/js/Gruntfile.js +++ b/js/Gruntfile.js @@ -15,11 +15,6 @@ module.exports = function (grunt) { minified: "../mopidy/frontends/http/data/mopidy.min.js" } }, - buster: { - test: { - config: "buster.js" - } - }, concat: { options: { banner: "<%= meta.banner %>", From 74b4fdc7ee471ad9ac477c719fc6ea2dcc5a6019 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Fri, 29 Mar 2013 13:51:28 +0100 Subject: [PATCH 2/4] js: Make test suite run on Node.js using faye-websocket --- js/buster.js | 10 +++++++++- js/package.json | 5 +++++ js/src/mopidy.js | 34 ++++++++++++++++++++++++++-------- js/test/mopidy-test.js | 35 ++++++++++++++++++++++++----------- 4 files changed, 64 insertions(+), 20 deletions(-) diff --git a/js/buster.js b/js/buster.js index f789885a..37f41d8a 100644 --- a/js/buster.js +++ b/js/buster.js @@ -1,9 +1,17 @@ var config = module.exports; -config["tests"] = { +config.browser_tests = { environment: "browser", libs: ["lib/**/*.js"], sources: ["src/**/*.js"], testHelpers: ["test/**/*-helper.js"], tests: ["test/**/*-test.js"] }; + +config.node_tests = { + environment: "node", + libs: ["lib/**/*.js"], + sources: ["src/**/*.js"], + testHelpers: ["test/**/*-helper.js"], + tests: ["test/**/*-test.js"] +}; diff --git a/js/package.json b/js/package.json index 6638c705..f83c9273 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,11 @@ { "name": "mopidy", "version": "0.0.0", + "dependencies": { + "bane": "~0.4.0", + "faye-websocket": "~0.4.4", + "when": "~1.8.1" + }, "devDependencies": { "buster": "~0.6.12", "grunt": "~0.4.0", diff --git a/js/src/mopidy.js b/js/src/mopidy.js index 5a75a836..011aec09 100644 --- a/js/src/mopidy.js +++ b/js/src/mopidy.js @@ -1,4 +1,10 @@ -/*global bane:false, when:false*/ +/*global exports:false, require:false*/ + +if (typeof module === "object" && typeof require === "function") { + var bane = require("bane"); + var websocket = require("faye-websocket"); + var when = require("when"); +} function Mopidy(settings) { if (!(this instanceof Mopidy)) { @@ -20,9 +26,17 @@ function Mopidy(settings) { } } +if (typeof module === "object" && typeof require === "function") { + Mopidy.WebSocket = websocket.Client; +} else { + Mopidy.WebSocket = window.WebSocket; +} + Mopidy.prototype._configure = function (settings) { + var currentHost = (typeof document !== "undefined" && + document.location.host) || "localhost"; settings.webSocketUrl = settings.webSocketUrl || - "ws://" + document.location.host + "/mopidy/ws/"; + "ws://" + currentHost + "/mopidy/ws/"; if (settings.autoConnect !== false) { settings.autoConnect = true; @@ -35,7 +49,7 @@ Mopidy.prototype._configure = function (settings) { }; Mopidy.prototype._getConsole = function () { - var console = window.console || {}; + var console = typeof console !== "undefined" && console || {}; console.log = console.log || function () {}; console.warn = console.warn || function () {}; @@ -63,7 +77,7 @@ Mopidy.prototype._delegateEvents = function () { Mopidy.prototype.connect = function () { if (this._webSocket) { - if (this._webSocket.readyState === WebSocket.OPEN) { + if (this._webSocket.readyState === Mopidy.WebSocket.OPEN) { return; } else { this._webSocket.close(); @@ -71,7 +85,7 @@ Mopidy.prototype.connect = function () { } this._webSocket = this._settings.webSocket || - new WebSocket(this._settings.webSocketUrl); + new Mopidy.WebSocket(this._settings.webSocketUrl); this._webSocket.onclose = function (close) { this.emit("websocket:close", close); @@ -136,17 +150,17 @@ Mopidy.prototype._send = function (message) { var deferred = when.defer(); switch (this._webSocket.readyState) { - case WebSocket.CONNECTING: + case Mopidy.WebSocket.CONNECTING: deferred.resolver.reject({ message: "WebSocket is still connecting" }); break; - case WebSocket.CLOSING: + case Mopidy.WebSocket.CLOSING: deferred.resolver.reject({ message: "WebSocket is closing" }); break; - case WebSocket.CLOSED: + case Mopidy.WebSocket.CLOSED: deferred.resolver.reject({ message: "WebSocket is closed" }); @@ -280,3 +294,7 @@ Mopidy.prototype._snakeToCamel = function (name) { return match.toUpperCase().replace("_", ""); }); }; + +if (typeof exports === "object") { + exports.Mopidy = Mopidy; +} diff --git a/js/test/mopidy-test.js b/js/test/mopidy-test.js index 8842ebf4..b694fd7e 100644 --- a/js/test/mopidy-test.js +++ b/js/test/mopidy-test.js @@ -1,4 +1,10 @@ -/*global buster:false, assert:false, refute:false, when:false, Mopidy:false*/ +/*global require:false, assert:false, refute:false*/ + +if (typeof module === "object" && typeof require === "function") { + var buster = require("buster"); + var Mopidy = require("../src/mopidy").Mopidy; + var when = require("when"); +} buster.testCase("Mopidy", { setUp: function () { @@ -14,10 +20,11 @@ buster.testCase("Mopidy", { fakeWebSocket.OPEN = 1; fakeWebSocket.CLOSING = 2; fakeWebSocket.CLOSED = 3; - this.realWebSocket = WebSocket; - window.WebSocket = fakeWebSocket; - this.webSocketConstructorStub = this.stub(window, "WebSocket"); + this.realWebSocket = Mopidy.WebSocket; + Mopidy.WebSocket = fakeWebSocket; + + this.webSocketConstructorStub = this.stub(Mopidy, "WebSocket"); this.webSocket = { close: this.stub(), @@ -27,15 +34,18 @@ buster.testCase("Mopidy", { }, tearDown: function () { - window.WebSocket = this.realWebSocket; + Mopidy.WebSocket = this.realWebSocket; }, "constructor": { "connects when autoConnect is true": function () { new Mopidy({autoConnect: true}); + var currentHost = typeof document !== "undefined" && + document.location.host || "localhost"; + assert.calledOnceWith(this.webSocketConstructorStub, - "ws://" + document.location.host + "/mopidy/ws/"); + "ws://" + currentHost + "/mopidy/ws/"); }, "does not connect when autoConnect is false": function () { @@ -67,12 +77,15 @@ buster.testCase("Mopidy", { mopidy.connect(); + var currentHost = typeof document !== "undefined" && + document.location.host || "localhost"; + assert.calledOnceWith(this.webSocketConstructorStub, - "ws://" + document.location.host + "/mopidy/ws/"); + "ws://" + currentHost + "/mopidy/ws/"); }, "does nothing when the WebSocket is open": function () { - this.webSocket.readyState = WebSocket.OPEN; + this.webSocket.readyState = Mopidy.WebSocket.OPEN; var mopidy = new Mopidy({webSocket: this.webSocket}); mopidy.connect(); @@ -367,7 +380,7 @@ buster.testCase("Mopidy", { }, "immediately rejects request if CONNECTING": function (done) { - this.mopidy._webSocket.readyState = WebSocket.CONNECTING; + this.mopidy._webSocket.readyState = Mopidy.WebSocket.CONNECTING; var promise = this.mopidy._send({method: "foo"}); @@ -381,7 +394,7 @@ buster.testCase("Mopidy", { }, "immediately rejects request if CLOSING": function (done) { - this.mopidy._webSocket.readyState = WebSocket.CLOSING; + this.mopidy._webSocket.readyState = Mopidy.WebSocket.CLOSING; var promise = this.mopidy._send({method: "foo"}); @@ -395,7 +408,7 @@ buster.testCase("Mopidy", { }, "immediately rejects request if CLOSED": function (done) { - this.mopidy._webSocket.readyState = WebSocket.CLOSED; + this.mopidy._webSocket.readyState = Mopidy.WebSocket.CLOSED; var promise = this.mopidy._send({method: "foo"}); From 461265f121415b556ba4cfb3cefa75e6eb6a5e49 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 30 Mar 2013 01:09:34 +0100 Subject: [PATCH 3/4] docs: Add Node.js installation instructions --- mopidy/frontends/http/__init__.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/mopidy/frontends/http/__init__.py b/mopidy/frontends/http/__init__.py index ab8dff42..3be4993e 100644 --- a/mopidy/frontends/http/__init__.py +++ b/mopidy/frontends/http/__init__.py @@ -128,8 +128,8 @@ you quickly started with working on your client instead of figuring out how to communicate with Mopidy. -Getting the library -------------------- +Getting the library for browser use +----------------------------------- Regular and minified versions of Mopidy.js, ready for use, is installed together with Mopidy. When the HTTP frontend is running, the files are @@ -154,6 +154,25 @@ the Git repo at: - ``mopidy/frontends/http/data/mopidy.js`` - ``mopidy/frontends/http/data/mopidy.min.js`` + +Getting the library for Node.js use +----------------------------------- + +If you want to use Mopidy.js from Node.js instead of a browser, you can install +Mopidy.js using npm:: + + npm install mopidy + +After npm completes, you can import Mopidy.js using ``require()``: + +.. code-block:: js + + var Mopidy = require("mopidy").Mopidy; + + +Getting the library for development on the library +-------------------------------------------------- + If you want to work on the Mopidy.js library itself, you'll find a complete development setup in the ``js/`` dir in our repo. The instructions in ``js/README.rst`` will guide you on your way. @@ -170,8 +189,8 @@ Once you got Mopidy.js loaded, you need to create an instance of the wrapper: When you instantiate ``Mopidy()`` without arguments, it will connect to the WebSocket at ``/mopidy/ws/`` on the current host. Thus, if you don't host -your web client using Mopidy's web server, you'll need to pass the URL to the -WebSocket end point: +your web client using Mopidy's web server, or if you use Mopidy.js from a +Node.js environment, you'll need to pass the URL to the WebSocket end point: .. code-block:: js From 5e374350f5d3debd4e4a45dc215aa7ecdbf59125 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 30 Mar 2013 01:18:31 +0100 Subject: [PATCH 4/4] js: Add more metadata to package.json for npm publishing --- js/README.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ js/README.rst | 62 ------------------------------------- js/package.json | 14 ++++++++- 3 files changed, 95 insertions(+), 63 deletions(-) create mode 100644 js/README.md delete mode 100644 js/README.rst diff --git a/js/README.md b/js/README.md new file mode 100644 index 00000000..9601b64a --- /dev/null +++ b/js/README.md @@ -0,0 +1,82 @@ +Mopidy.js +========= + +Mopidy.js is a JavaScript library that is installed as a part of Mopidy's HTTP +frontend or from npm. The library makes Mopidy's core API available from the +browser or a Node.js environment, using JSON-RPC messages over a WebSocket to +communicate with Mopidy. + + +Getting it for browser use +-------------------------- + +Regular and minified versions of Mopidy.js, ready for use, is installed +together with Mopidy. When the HTTP frontend is running, the files are +available at: + +- http://localhost:6680/mopidy/mopidy.js +- http://localhost:6680/mopidy/mopidy.min.js + +You may need to adjust hostname and port for your local setup. + +In the source repo, you can find the files at: + +- `mopidy/frontends/http/data/mopidy.js` +- `mopidy/frontends/http/data/mopidy.min.js` + + +Getting it for Node.js use +-------------------------- + +If you want to use Mopidy.js from Node.js instead of a browser, you can install +Mopidy.js using npm: + + npm install mopidy + +After npm completes, you can import Mopidy.js using ``require()``: + + var Mopidy = require("mopidy").Mopidy; + + +Using the library +----------------- + +See Mopidy's [HTTP frontend +documentation](http://docs.mopidy.com/en/latest/modules/frontends/http/). + + +Building from source +-------------------- + +1. Install [Node.js](http://nodejs.org/) and npm. There is a PPA if you're + running Ubuntu: + + sudo apt-get install python-software-properties + sudo add-apt-repository ppa:chris-lea/node.js + sudo apt-get update + sudo apt-get install nodejs npm + +2. Enter the `js/` in Mopidy's Git repo dir and install all dependencies: + + cd js/ + npm install + +That's it. + +You can now run the tests: + + npm test + +To run tests automatically when you save a file: + + npm run-script watch + +To run tests, concatenate, minify the source, and update the JavaScript files +in `mopidy/frontends/http/data/`: + + npm run-script build + +To run other [grunt](http://gruntjs.com/) targets which isn't predefined in +`package.json` and thus isn't available through `npm run-script`: + + PATH=./node_modules/.bin:$PATH grunt foo diff --git a/js/README.rst b/js/README.rst deleted file mode 100644 index e8782213..00000000 --- a/js/README.rst +++ /dev/null @@ -1,62 +0,0 @@ -********* -Mopidy.js -********* - -This is the source for the JavaScript library that is installed as a part of -Mopidy's HTTP frontend. The library makes Mopidy's core API available from the -browser, using JSON-RPC messages over a WebSocket to communicate with Mopidy. - - -Getting it -========== - -Regular and minified versions of Mopidy.js, ready for use, is installed -together with Mopidy. When the HTTP frontend is running, the files are -available at: - -- http://localhost:6680/mopidy/mopidy.js -- http://localhost:6680/mopidy/mopidy.min.js - -You may need to adjust hostname and port for your local setup. - -In the source repo, you can find the files at: - -- ``mopidy/frontends/http/data/mopidy.js`` -- ``mopidy/frontends/http/data/mopidy.min.js`` - - -Building from source -==================== - -1. Install `Node.js `_ and npm. There is a PPA if you're - running Ubuntu:: - - sudo apt-get install python-software-properties - sudo add-apt-repository ppa:chris-lea/node.js - sudo apt-get update - sudo apt-get install nodejs npm - -2. Enter the ``js/`` dir and install development dependencies:: - - cd js/ - npm install - -That's it. - -You can now run the tests:: - - npm test - -To run tests automatically when you save a file:: - - npm run-script watch - -To run tests, concatenate, minify the source, and update the JavaScript files -in ``mopidy/frontends/http/data/``:: - - npm run-script build - -To run other `grunt `_ targets which isn't predefined in -``package.json`` and thus isn't available through ``npm run-script``:: - - PATH=./node_modules/.bin:$PATH grunt foo diff --git a/js/package.json b/js/package.json index f83c9273..d3398ca0 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,18 @@ { "name": "mopidy", - "version": "0.0.0", + "version": "0.0.1", + "description": "Client lib for controlling a Mopidy music server over a WebSocket", + "homepage": "http://www.mopidy.com/", + "author": { + "name": "Stein Magnus Jodal", + "email": "stein.magnus@jodal.no", + "url": "http://www.jodal.no" + }, + "repository": { + "type": "git", + "url": "git://github.com/mopidy/mopidy.git" + }, + "main": "src/mopidy.js", "dependencies": { "bane": "~0.4.0", "faye-websocket": "~0.4.4",