leonidas 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +1 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +105 -0
- data/LICENSE +21 -0
- data/Manifest +63 -0
- data/README.md +213 -0
- data/Rakefile +42 -0
- data/assets/scripts/coffee/leonidas/client.coffee +15 -0
- data/assets/scripts/coffee/leonidas/commander.coffee +34 -0
- data/assets/scripts/coffee/leonidas/commands/command.coffee +9 -0
- data/assets/scripts/coffee/leonidas/commands/organizer.coffee +24 -0
- data/assets/scripts/coffee/leonidas/commands/processor.coffee +13 -0
- data/assets/scripts/coffee/leonidas/commands/stabilizer.coffee +13 -0
- data/assets/scripts/coffee/leonidas/commands/synchronizer.coffee +38 -0
- data/assets/scripts/js/lib/jquery.js +6 -0
- data/bin/leonidas.js +178 -0
- data/config/assets.rb +7 -0
- data/leonidas.gemspec +36 -0
- data/lib/leonidas.rb +14 -0
- data/lib/leonidas/app/app.rb +80 -0
- data/lib/leonidas/app/connection.rb +20 -0
- data/lib/leonidas/app/repository.rb +41 -0
- data/lib/leonidas/commands/aggregator.rb +31 -0
- data/lib/leonidas/commands/command.rb +24 -0
- data/lib/leonidas/commands/handler.rb +21 -0
- data/lib/leonidas/commands/processor.rb +30 -0
- data/lib/leonidas/dsl/configuration_expression.rb +17 -0
- data/lib/leonidas/memory_layer/memory_registry.rb +33 -0
- data/lib/leonidas/persistence_layer/persister.rb +54 -0
- data/lib/leonidas/persistence_layer/state_builder.rb +17 -0
- data/lib/leonidas/persistence_layer/state_loader.rb +22 -0
- data/lib/leonidas/routes/sync.rb +45 -0
- data/lib/leonidas/symbols.rb +17 -0
- data/spec/jasmine/jasmine.yml +44 -0
- data/spec/jasmine/runner.html +77 -0
- data/spec/jasmine/support/classes.coffee +16 -0
- data/spec/jasmine/support/helpers.coffee +22 -0
- data/spec/jasmine/support/mocks.coffee +19 -0
- data/spec/jasmine/support/objects.coffee +11 -0
- data/spec/jasmine/support/requirements.coffee +1 -0
- data/spec/jasmine/tests/client_spec.coffee +20 -0
- data/spec/jasmine/tests/commander_spec.coffee +69 -0
- data/spec/jasmine/tests/commands/command_spec.coffee +12 -0
- data/spec/jasmine/tests/commands/organizer_spec.coffee +70 -0
- data/spec/jasmine/tests/commands/processor_spec.coffee +22 -0
- data/spec/jasmine/tests/commands/stabilizer_spec.coffee +30 -0
- data/spec/jasmine/tests/commands/synchronizer_spec.coffee +72 -0
- data/spec/rspec/spec_helper.rb +4 -0
- data/spec/rspec/support/classes/app.rb +26 -0
- data/spec/rspec/support/classes/commands.rb +52 -0
- data/spec/rspec/support/classes/persistence.rb +56 -0
- data/spec/rspec/support/config.rb +3 -0
- data/spec/rspec/support/mocks.rb +15 -0
- data/spec/rspec/support/objects.rb +11 -0
- data/spec/rspec/unit/app/app_spec.rb +185 -0
- data/spec/rspec/unit/app/repository_spec.rb +114 -0
- data/spec/rspec/unit/commands/aggregator_spec.rb +103 -0
- data/spec/rspec/unit/commands/command.rb +17 -0
- data/spec/rspec/unit/commands/processor_spec.rb +30 -0
- data/spec/rspec/unit/dsl/configuration_expression_spec.rb +32 -0
- data/spec/rspec/unit/leonidas_spec.rb +26 -0
- data/spec/rspec/unit/memory_layer/memory_registry_spec.rb +85 -0
- data/spec/rspec/unit/persistence_layer/persister_spec.rb +84 -0
- data/spec/rspec/unit/persistence_layer/state_loader_spec.rb +29 -0
- metadata +166 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module App
|
|
3
|
+
|
|
4
|
+
class Connection
|
|
5
|
+
include ::Leonidas::Commands::Aggregator
|
|
6
|
+
|
|
7
|
+
attr_reader :id, :active_commands
|
|
8
|
+
attr_accessor :last_update
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@id = SecureRandom.uuid
|
|
12
|
+
@last_update = Time.now.to_i
|
|
13
|
+
@active_commands = [ ]
|
|
14
|
+
@inactive_commands = [ ]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module App
|
|
3
|
+
module AppRepository
|
|
4
|
+
def app_repository
|
|
5
|
+
@repository ||= Repository.new
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class Repository
|
|
10
|
+
|
|
11
|
+
def find(app_name)
|
|
12
|
+
app = ::Leonidas::MemoryLayer::MemoryRegistry.retrieve_app app_name
|
|
13
|
+
if app.nil?
|
|
14
|
+
app = ::Leonidas::PersistenceLayer::Persister.load app_name
|
|
15
|
+
watch app unless app.nil?
|
|
16
|
+
end
|
|
17
|
+
app
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def watch(app)
|
|
21
|
+
::Leonidas::MemoryLayer::MemoryRegistry.register_app! app
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def save(app)
|
|
25
|
+
::Leonidas::PersistenceLayer::Persister.persist app
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def archive(app)
|
|
29
|
+
::Leonidas::MemoryLayer::MemoryRegistry.close_app! app.name
|
|
30
|
+
::Leonidas::PersistenceLayer::Persister.persist app
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def delete(app)
|
|
34
|
+
::Leonidas::MemoryLayer::MemoryRegistry.close_app! app.name
|
|
35
|
+
::Leonidas::PersistenceLayer::Persister.delete app
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module Commands
|
|
3
|
+
|
|
4
|
+
module Aggregator
|
|
5
|
+
|
|
6
|
+
def add_command!(command)
|
|
7
|
+
raise TypeError, "Argument must be a Leonidas::Commands::Command" unless command.is_a? ::Leonidas::Commands::Command
|
|
8
|
+
@active_commands << command
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def add_commands!(commands)
|
|
12
|
+
commands.each {|command| add_command!(command)}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def commands_through(timestamp)
|
|
16
|
+
@active_commands.select {|command| command.timestamp <= timestamp}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def commands_since(timestamp)
|
|
20
|
+
@active_commands.select {|command| command.timestamp > timestamp}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def deactivate_commands!(commands)
|
|
24
|
+
commands.each {|command| @inactive_commands << command if @active_commands.include? command}
|
|
25
|
+
@active_commands.select! {|command| not commands.include? command}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module Commands
|
|
3
|
+
|
|
4
|
+
class Command
|
|
5
|
+
|
|
6
|
+
attr_reader :name, :data, :timestamp, :connection
|
|
7
|
+
|
|
8
|
+
def initialize(name, data, timestamp, connection)
|
|
9
|
+
@name = name
|
|
10
|
+
@data = data
|
|
11
|
+
@timestamp = timestamp
|
|
12
|
+
|
|
13
|
+
raise TypeError, "Argument must be a Leonidas::App::Connection" unless connection.is_a? ::Leonidas::App::Connection
|
|
14
|
+
@connection = connection
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_hash
|
|
18
|
+
{ name: @name, data: @data, timestamp: @timestamp, connection: @connection.id }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module Commands
|
|
3
|
+
|
|
4
|
+
class Processor
|
|
5
|
+
|
|
6
|
+
def initialize(handlers)
|
|
7
|
+
@handlers = [ ]
|
|
8
|
+
handlers.each do |handler|
|
|
9
|
+
raise TypeError, "Argument must include Leonidas::Commands::Handler" unless handler.class < ::Leonidas::Commands::Handler
|
|
10
|
+
@handlers << handler
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def process(commands, persist=false)
|
|
15
|
+
commands.sort! {|command1, command2| command1.timestamp <=> command2.timestamp}
|
|
16
|
+
commands.each do |command|
|
|
17
|
+
raise TypeError, "Argument must be a Leonidas::Commands::Command" unless command.is_a? ::Leonidas::Commands::Command
|
|
18
|
+
@handlers.each do |command_handler|
|
|
19
|
+
if command_handler.handles? command
|
|
20
|
+
command_handler.run(command)
|
|
21
|
+
command_handler.persist(command) if persist
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module Dsl
|
|
3
|
+
|
|
4
|
+
class ConfigurationExpression
|
|
5
|
+
|
|
6
|
+
def persister_class_is(persister_class)
|
|
7
|
+
::Leonidas::PersistenceLayer::Persister.set_app_persister! persister_class.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def add_app_state_builder(builder_class)
|
|
11
|
+
::Leonidas::PersistenceLayer::Persister.add_state_builder! builder_class.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module MemoryLayer
|
|
3
|
+
|
|
4
|
+
class MemoryRegistry
|
|
5
|
+
|
|
6
|
+
@@apps = { }
|
|
7
|
+
|
|
8
|
+
def self.register_app!(app)
|
|
9
|
+
raise TypeError, "Argument must include Leonidas::App::App" unless app.class < ::Leonidas::App::App
|
|
10
|
+
raise StandardError, "An app with the name '#{app.name}' is already registered" if ::Leonidas::MemoryLayer::MemoryRegistry.has_app? app.name
|
|
11
|
+
@@apps[app.name] = app
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.retrieve_app(name)
|
|
15
|
+
@@apps[name]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.has_app?(name)
|
|
19
|
+
not MemoryRegistry.retrieve_app(name).nil?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.close_app!(name)
|
|
23
|
+
@@apps.delete name
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.clear_registry!
|
|
27
|
+
@@apps = { }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module PersistenceLayer
|
|
3
|
+
module AppPersister
|
|
4
|
+
|
|
5
|
+
def load(app_name)
|
|
6
|
+
# load your app
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def persist(app)
|
|
10
|
+
# save your app (this excludes state saving, that happens in the command handlers)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def delete(app)
|
|
14
|
+
# delete your app
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class Persister
|
|
20
|
+
|
|
21
|
+
@@persister = nil
|
|
22
|
+
|
|
23
|
+
def self.set_app_persister!(persister)
|
|
24
|
+
raise TypeError, "Argument must include Leonidas::PersistenceLayer::AppPersister" unless persister.class < ::Leonidas::PersistenceLayer::AppPersister
|
|
25
|
+
@@persister = persister
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
@@state_loader = ::Leonidas::PersistenceLayer::StateLoader.new
|
|
29
|
+
|
|
30
|
+
def self.add_state_builder!(builder)
|
|
31
|
+
@@state_loader.add_builder! builder
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.load(app_name)
|
|
35
|
+
app = @@persister.load app_name unless @@persister.nil?
|
|
36
|
+
unless app.nil?
|
|
37
|
+
@@state_loader.load_state app
|
|
38
|
+
app.process_commands!
|
|
39
|
+
end
|
|
40
|
+
app
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.persist(app)
|
|
44
|
+
@@persister.persist app unless @@persister.nil?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.delete(app)
|
|
48
|
+
@@persister.delete app unless @@persister.nil?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module PersistenceLayer
|
|
3
|
+
|
|
4
|
+
class StateLoader
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@builders = [ ]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def add_builder!(builder)
|
|
11
|
+
raise TypeError, "Argument must include Leonidas::PersistenceLayer::StateBuilder" unless builder.class < ::Leonidas::PersistenceLayer::StateBuilder
|
|
12
|
+
@builders << builder
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def load_state(app)
|
|
16
|
+
@builders.each {|builder| return builder.build_stable_state app if builder.handles? app}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Leonidas
|
|
2
|
+
module Routes
|
|
3
|
+
|
|
4
|
+
class SyncApp < Sinatra::Base
|
|
5
|
+
include ::Leonidas::App::AppRepository
|
|
6
|
+
|
|
7
|
+
get '/:app_name' do
|
|
8
|
+
content_type "application/json"
|
|
9
|
+
|
|
10
|
+
app = app_repository.find params[:app_name]
|
|
11
|
+
|
|
12
|
+
new_commands = params[:clients].reduce([ ]) {|commands, client| commands.concat app.connection(client[:id]).commands_since(client[:lastUpdate])}
|
|
13
|
+
additional_clients = app.connections.select {|connection| connection.id != params[:clientId]}
|
|
14
|
+
|
|
15
|
+
{
|
|
16
|
+
success: true,
|
|
17
|
+
message: 'commands retrieved',
|
|
18
|
+
data: {
|
|
19
|
+
commands: new_commands.map {|command| command.to_hash},
|
|
20
|
+
currentClients: additional_clients.map {|connection| { id: connection.id, lastUpdate: connection.last_update }},
|
|
21
|
+
stableTimestamp: app.stable_timestamp
|
|
22
|
+
}
|
|
23
|
+
}.to_json
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
post '/:app_name' do
|
|
27
|
+
content_type "application/json"
|
|
28
|
+
|
|
29
|
+
app = app_repository.find params[:app_name]
|
|
30
|
+
connection = app.connection params[:clientId]
|
|
31
|
+
|
|
32
|
+
commands = params[:commands].map {|command| ::Leonidas::Commands::Command.new(command.name, command.data, command.timestamp, connection)}
|
|
33
|
+
connection.add_commands! commands
|
|
34
|
+
|
|
35
|
+
{
|
|
36
|
+
success: true,
|
|
37
|
+
message: 'commands received',
|
|
38
|
+
data: { }
|
|
39
|
+
}.to_json
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "keystone"
|
|
2
|
+
|
|
3
|
+
module Leonidas
|
|
4
|
+
|
|
5
|
+
def self.pipeline
|
|
6
|
+
@@pipeline ||= ::Keystone.bootstrap("#{root_path}/config/assets.rb")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.keystone_compiler
|
|
10
|
+
@@keystone_compiler ||= pipeline.compiler("leonidas.js")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.root_path
|
|
14
|
+
File.expand_path("#{File.dirname(__FILE__)}/../../")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
runner_output: "spec/jasmine/runner.html"
|
|
2
|
+
|
|
3
|
+
# src_files
|
|
4
|
+
#
|
|
5
|
+
# Return an array of filepaths relative to src_dir to include before jasmine specs.
|
|
6
|
+
# Default: []
|
|
7
|
+
src_files:
|
|
8
|
+
- bin/leonidas.js
|
|
9
|
+
|
|
10
|
+
# stylesheets
|
|
11
|
+
#
|
|
12
|
+
# Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
|
|
13
|
+
# Default: []
|
|
14
|
+
stylesheets:
|
|
15
|
+
|
|
16
|
+
# helpers
|
|
17
|
+
#
|
|
18
|
+
# Return an array of filepaths relative to spec_dir to include before jasmine specs.
|
|
19
|
+
# Default: ["helpers/**/*.js"]
|
|
20
|
+
helpers:
|
|
21
|
+
- support/requirements.coffee
|
|
22
|
+
- support/helpers.coffee
|
|
23
|
+
- support/objects.coffee
|
|
24
|
+
- support/classes.coffee
|
|
25
|
+
- support/mocks.coffee
|
|
26
|
+
|
|
27
|
+
# spec_files
|
|
28
|
+
#
|
|
29
|
+
# Return an array of filepaths relative to spec_dir to include.
|
|
30
|
+
# Default: ["**/*[sS]pec.js"]
|
|
31
|
+
spec_files:
|
|
32
|
+
- ./**/*_spec.coffee
|
|
33
|
+
|
|
34
|
+
# src_dir
|
|
35
|
+
#
|
|
36
|
+
# Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
|
|
37
|
+
# Default: project root
|
|
38
|
+
src_dir:
|
|
39
|
+
|
|
40
|
+
# spec_dir
|
|
41
|
+
#
|
|
42
|
+
# Spec directory path. Your spec_files must be returned relative to this path.
|
|
43
|
+
# Default: spec/javascripts
|
|
44
|
+
spec_dir: spec/jasmine
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
|
|
5
|
+
<title>Jasmine Test Runner - Generated by jasmine-headless-webkit</title>
|
|
6
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/prolog.js"></script>
|
|
7
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-core-1.3.1/lib/jasmine-core/jasmine.js"></script>
|
|
8
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-core-1.3.1/lib/jasmine-core/jasmine-html.js"></script>
|
|
9
|
+
<link rel="stylesheet" href="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-core-1.3.1/lib/jasmine-core/jasmine.css" type="text/css" />
|
|
10
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/jasmine-extensions.js"></script>
|
|
11
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/intense.js"></script>
|
|
12
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/headless_reporter_result.js"></script>
|
|
13
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js"></script>
|
|
14
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/jsDump.js"></script>
|
|
15
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/vendor/ruby/1.9.1/gems/jasmine-headless-webkit-0.8.4/vendor/assets/javascripts/beautify-html.js"></script>
|
|
16
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/bin/leonidas.js"></script>
|
|
17
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/requirements.coffee.js"></script>
|
|
18
|
+
<script type="text/javascript">window.CSTF['requirements.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/requirements.coffee';</script>
|
|
19
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/helpers.coffee.js"></script>
|
|
20
|
+
<script type="text/javascript">window.CSTF['helpers.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/helpers.coffee';</script>
|
|
21
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/objects.coffee.js"></script>
|
|
22
|
+
<script type="text/javascript">window.CSTF['objects.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/objects.coffee';</script>
|
|
23
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/classes.coffee.js"></script>
|
|
24
|
+
<script type="text/javascript">window.CSTF['classes.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/classes.coffee';</script>
|
|
25
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/mocks.coffee.js"></script>
|
|
26
|
+
<script type="text/javascript">window.CSTF['mocks.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/support/mocks.coffee';</script>
|
|
27
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/synchronizer_spec.coffee.js"></script>
|
|
28
|
+
<script type="text/javascript">window.CSTF['synchronizer_spec.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/synchronizer_spec.coffee';</script>
|
|
29
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commander_spec.coffee.js"></script>
|
|
30
|
+
<script type="text/javascript">window.CSTF['commander_spec.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commander_spec.coffee';</script>
|
|
31
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/stabilizer_spec.coffee.js"></script>
|
|
32
|
+
<script type="text/javascript">window.CSTF['stabilizer_spec.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/stabilizer_spec.coffee';</script>
|
|
33
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/organizer_spec.coffee.js"></script>
|
|
34
|
+
<script type="text/javascript">window.CSTF['organizer_spec.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/organizer_spec.coffee';</script>
|
|
35
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/command_spec.coffee.js"></script>
|
|
36
|
+
<script type="text/javascript">window.CSTF['command_spec.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/command_spec.coffee';</script>
|
|
37
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/client_spec.coffee.js"></script>
|
|
38
|
+
<script type="text/javascript">window.CSTF['client_spec.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/client_spec.coffee';</script>
|
|
39
|
+
<script type="text/javascript" src="/Users/tshelburne/Sites/musicone/leonidas/.jhw-cache/coffee_script/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/processor_spec.coffee.js"></script>
|
|
40
|
+
<script type="text/javascript">window.CSTF['processor_spec.coffee.js'] = '/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/processor_spec.coffee';</script>
|
|
41
|
+
<script type="text/javascript">
|
|
42
|
+
if (window.JHW) { HeadlessReporterResult.specLineNumbers = {"/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/synchronizer_spec.coffee":{"Synchronizer":[6],"#push":[23],"when successful":[28,47],"will mark the commands pushed as synced":[30],"will not mark unsynced commands added since push was called as synced":[36],"#pull":[45],"will update the list of external clients and their latest timestamps":[53],"will add the list of received commands as synced commands":[57],"will lock to a new stable state":[64],"will deactivate stable commands":[68]},"/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commander_spec.coffee":{"Commander":[7],"::default":[23],"will return a default commander using the built in classes":[25],"#startSync":[29],"will set the synchronizer to begin pushing updates":[34],"will set the synchronizer to begin pulling updates":[39],"#stopSync":[44],"will stop the synchronizer from pushing updates":[49],"will stop the synchronizer from pulling updates":[55],"#issueCommand":[61],"will generate an unsynchronized command":[63],"will run the command to update the local client state":[67]},"/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/stabilizer_spec.coffee":{"Stabilizer":[6],"#stabilize":[18],"will update the locked state to the state at the given timestamp":[20],"will deactivate the stable commands in the command organizer":[24],"will process the remaining active commands to leave the active state entirely current":[28]},"/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/organizer_spec.coffee":{"Organizer":[3],"#addCommand":[14],"will add unsynced commands":[16],"will add synced commands":[20],"#addCommands":[24],"will add multiple unsynced commands":[26],"will add multiple synced commands":[30],"#markAsSynced":[34],"will add the requested commands to the syncedCommands list":[36],"will remove the requested commands from the unsyncedCommands list":[41],"#markAsInactive":[46],"will add the requested commands to the inactiveCommands list":[48],"will remove requested commands from the syncedCommands list":[53],"#activeCommands":[58],"will return a concatenated list of synced and unsynced commands":[60],"will sort the list of commands by timestamp":[67]},"/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/command_spec.coffee":{"Command":[3],"#toHash":[9],"will return the command serialized as a hash":[11]},"/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/client_spec.coffee":{"Client":[3],"#revertState":[10],"will revert the active state to the locked state":[12],"#lockState":[16],"will lock the state to the active state":[18]},"/Users/tshelburne/Sites/musicone/leonidas/spec/jasmine/tests/commands/processor_spec.coffee":{"Processor":[4],"#processCommand":[12],"will run a command":[14],"#processCommands":[18],"will run multiple commands":[20]}}; }
|
|
43
|
+
</script>
|
|
44
|
+
</head>
|
|
45
|
+
<body>
|
|
46
|
+
<script type="text/javascript">
|
|
47
|
+
jasmine.getEnv().console = {
|
|
48
|
+
log: function(msg) { JHW.stdout.puts(msg) }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
window._onload = window.onload;
|
|
52
|
+
|
|
53
|
+
window.onload = function() {
|
|
54
|
+
if (window._onload && (window._onload != window.onload)) {
|
|
55
|
+
window._onload();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (window.JHW) {
|
|
59
|
+
jasmine.getEnv().addReporter(new jasmine.HeadlessConsoleReporter());
|
|
60
|
+
} else {
|
|
61
|
+
types = [ 'HtmlReporter', 'TrivialReporter' ];
|
|
62
|
+
|
|
63
|
+
for (var i = 0, j = types.length; i < j; ++i) {
|
|
64
|
+
var type = jasmine[types[i]]
|
|
65
|
+
if (type) {
|
|
66
|
+
jasmine.getEnv().addReporter(new type());
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
jasmine.getEnv().execute();
|
|
73
|
+
}
|
|
74
|
+
</script>
|
|
75
|
+
</body>
|
|
76
|
+
</html>
|
|
77
|
+
|