mycroft 0.1.0
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +24 -0
- data/README.md +81 -0
- data/Rakefile +6 -0
- data/bin/mycroft-ruby +5 -0
- data/lib/mycroft.rb +14 -0
- data/lib/mycroft/cli.rb +39 -0
- data/lib/mycroft/client.rb +74 -0
- data/lib/mycroft/helpers.rb +40 -0
- data/lib/mycroft/messages.rb +92 -0
- data/lib/mycroft/templates/app_manifest +14 -0
- data/lib/mycroft/templates/app_template +21 -0
- data/lib/mycroft/version.rb +3 -0
- data/mycroft.gemspec +28 -0
- data/spec/helpers_spec.rb +63 -0
- data/spec/mock.rb +38 -0
- data/spec/spec_helper.rb +3 -0
- metadata +195 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Copyright (c) 2014, The Society of Software Engineers
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
* Redistributions of source code must retain the above copyright
|
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
|
10
|
+
documentation and/or other materials provided with the distribution.
|
|
11
|
+
* Neither the name of the Society of Software Engineers nor the
|
|
12
|
+
names of its contributors may be used to endorse or promote products
|
|
13
|
+
derived from this software without specific prior written permission.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE SOCIETY OF SOFTWARE ENGINEERS BE LIABLE FOR
|
|
19
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
22
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Mycroft
|
|
2
|
+
|
|
3
|
+
Gem for creating mycroft application in ruby.
|
|
4
|
+
|
|
5
|
+
### Install
|
|
6
|
+
Install bundler:
|
|
7
|
+
~~~
|
|
8
|
+
gem install bundler
|
|
9
|
+
~~~
|
|
10
|
+
|
|
11
|
+
From inside the ruby app directory
|
|
12
|
+
|
|
13
|
+
~~~
|
|
14
|
+
bundle install
|
|
15
|
+
rake install
|
|
16
|
+
~~~
|
|
17
|
+
If we ever put this on ruby gems:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
gem install mycroft
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Create a new App
|
|
24
|
+
`mycroft-ruby new [APPNAME]`
|
|
25
|
+
|
|
26
|
+
## Running your app
|
|
27
|
+
`ruby YOUR_APP.rb [--no-tls]`
|
|
28
|
+
|
|
29
|
+
### Example App
|
|
30
|
+
```ruby
|
|
31
|
+
require 'mycroft'
|
|
32
|
+
|
|
33
|
+
class MockAppRuby < Mycroft::Client
|
|
34
|
+
|
|
35
|
+
def initialize(host, port)
|
|
36
|
+
@key = ''
|
|
37
|
+
@cert = ''
|
|
38
|
+
@manifest = './mock_app_ruby.json'
|
|
39
|
+
@verified = false
|
|
40
|
+
super
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
on 'APP_DEPENDENCY' do |data|
|
|
44
|
+
up
|
|
45
|
+
broadcast({message: "I'm broadcasting things"})
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
Mycroft::start(MockAppRuby)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Overview of MockRubyApp
|
|
53
|
+
|
|
54
|
+
#### initialize
|
|
55
|
+
Specify the path to key, path to cert, path to app manifest, and whether it's verified or not. Set that to false.
|
|
56
|
+
|
|
57
|
+
#### on
|
|
58
|
+
For each of the different messages, you create an event handler using the `on` method. You can also do this for `CONNECT`, `CONNECTION_CLOSED`, and `ERROR`. You can create multiple handlers per message if that's what you want to do. The Base class creates 3 for you. On `APP_MANIFEST_OK` `@verified` is set to `true`. On `APP_MANIFEST_FAIL` and `MSG_GENERAL_FAILURE`, it raises an error. On `APP_DEPENDENCY`, `@depedencies` is updated with current dependencies.
|
|
59
|
+
|
|
60
|
+
### Helper Methods
|
|
61
|
+
|
|
62
|
+
#### up
|
|
63
|
+
Sends `APP_UP` to mycroft
|
|
64
|
+
|
|
65
|
+
#### down
|
|
66
|
+
Sends `APP_DOWN` to mycroft
|
|
67
|
+
|
|
68
|
+
#### in_use
|
|
69
|
+
Sends `APP_IN_USE` to mycroft
|
|
70
|
+
|
|
71
|
+
#### query(capability, action, data, priority = 30, instance_id = nil)
|
|
72
|
+
Sends a `MSG_QUERY` to mycroft
|
|
73
|
+
|
|
74
|
+
#### broadcast(content)
|
|
75
|
+
Sends a `MSG_BROADCAST` to mycroft
|
|
76
|
+
|
|
77
|
+
#### query_success(id, ret)
|
|
78
|
+
Sends a `MSG_QUERY_SUCCESS` to mycroft
|
|
79
|
+
|
|
80
|
+
#### query_fail(id, message)
|
|
81
|
+
Sends a `MSG_QUERY_FAIL` to mycroft
|
data/Rakefile
ADDED
data/bin/mycroft-ruby
ADDED
data/lib/mycroft.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'mycroft/version'
|
|
2
|
+
require 'mycroft/cli'
|
|
3
|
+
require 'mycroft/helpers'
|
|
4
|
+
require 'mycroft/messages'
|
|
5
|
+
require 'mycroft/client'
|
|
6
|
+
|
|
7
|
+
module Mycroft
|
|
8
|
+
extend self
|
|
9
|
+
MYCROFT_PORT = 1847
|
|
10
|
+
|
|
11
|
+
def start(app, host='localhost', port=MYCROFT_PORT)
|
|
12
|
+
app.new(host, port)
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/mycroft/cli.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'thor'
|
|
2
|
+
require 'active_support/lazy_load_hooks'
|
|
3
|
+
require 'active_support/core_ext/string'
|
|
4
|
+
require 'highline/import'
|
|
5
|
+
|
|
6
|
+
module Mycroft
|
|
7
|
+
class CLI < Thor
|
|
8
|
+
desc "new [APPNAME]", "create a new app with the name APPNAME"
|
|
9
|
+
def new(app_name=nil)
|
|
10
|
+
app_name = ask("App Name: ") if app_name.nil?
|
|
11
|
+
dn = ask("Display Name: ")
|
|
12
|
+
instance_id = ask("Instance Id: ")
|
|
13
|
+
desc = ask("Description: ")
|
|
14
|
+
camelcase = app_name.camelize
|
|
15
|
+
underscore = app_name.underscore
|
|
16
|
+
dashed = app_name.dasherize
|
|
17
|
+
path = "#{Gem.dir}/gems/mycroft-#{Mycroft::VERSION}/lib/mycroft/templates/"
|
|
18
|
+
app_template = File.read("#{path}/app_template")
|
|
19
|
+
app_template.gsub!(/%%APPNAME%%/, camelcase)
|
|
20
|
+
app_template.gsub!(/%%UNDERSCORE%%/, underscore)
|
|
21
|
+
|
|
22
|
+
app_manifest = File.read("#{path}/app_manifest")
|
|
23
|
+
app_manifest.gsub!(/%%DASHED%%/, dashed)
|
|
24
|
+
app_manifest.gsub!(/%%DISPLAYNAME%%/, dn)
|
|
25
|
+
app_manifest.gsub!(/%%INSTANCEID%%/, instance_id)
|
|
26
|
+
app_manifest.gsub!(/%%DESC%%/, desc)
|
|
27
|
+
|
|
28
|
+
app_file = File.open("./#{underscore}.rb", 'w')
|
|
29
|
+
app_file.puts app_template
|
|
30
|
+
app_file.close
|
|
31
|
+
puts "Successfully created #{underscore}.rb"
|
|
32
|
+
|
|
33
|
+
app_file = File.open("./app.json", 'w')
|
|
34
|
+
app_file.puts app_manifest
|
|
35
|
+
app_file.close
|
|
36
|
+
puts "Successfully created app.json"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'socket'
|
|
2
|
+
require 'io/wait'
|
|
3
|
+
|
|
4
|
+
module Mycroft
|
|
5
|
+
class Client
|
|
6
|
+
include Messages
|
|
7
|
+
|
|
8
|
+
def initialize(host, port)
|
|
9
|
+
@host = host
|
|
10
|
+
@port = port
|
|
11
|
+
@name ||= 'mycroft'
|
|
12
|
+
connect_to_mycroft
|
|
13
|
+
if @threaded
|
|
14
|
+
Thread.new do
|
|
15
|
+
setup
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
setup
|
|
19
|
+
end
|
|
20
|
+
rescue Exception => e
|
|
21
|
+
instance_exec(e, &@@handlers['ERROR']) unless @@handlers['ERROR'].nil?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def setup
|
|
25
|
+
send_manifest
|
|
26
|
+
instance_eval &@@handlers['CONNECT'] unless @@handlers['CONNECT'].nil?
|
|
27
|
+
run
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.on(type, &block)
|
|
31
|
+
@@handlers ||= {}
|
|
32
|
+
@@handlers[type] = block
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def run
|
|
36
|
+
loop do
|
|
37
|
+
if @client.ready?
|
|
38
|
+
size = @client.readline
|
|
39
|
+
data = @client.read(size.to_i)
|
|
40
|
+
parsed = parse_message(data)
|
|
41
|
+
unless @@handlers[parsed[:type]].nil?
|
|
42
|
+
instance_exec(parsed[:data], &@@handlers[parsed[:type]])
|
|
43
|
+
else
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
on_event_loop if methods.include?(:on_event_loop)
|
|
47
|
+
end
|
|
48
|
+
ensure
|
|
49
|
+
shutdown
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def shutdown
|
|
53
|
+
instance_eval &@@handlers['CONNECTION_CLOSED'] unless @@handlers['CONNECTION_CLOSED'].nil?
|
|
54
|
+
down
|
|
55
|
+
@client.close
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
on 'APP_MANIFEST_OK' do |data|
|
|
59
|
+
@verified = true
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
on 'APP_MANIFEST_FAIL' do |data|
|
|
63
|
+
raise 'Invalid application manifest'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
on 'MSG_GENERAL_FAILURE' do |data|
|
|
67
|
+
raise data.message
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
on 'APP_DEPENDENCY' do |data|
|
|
71
|
+
update_dependencies(data)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Mycroft
|
|
2
|
+
module Helpers
|
|
3
|
+
|
|
4
|
+
# Parses a message
|
|
5
|
+
def parse_message(msg)
|
|
6
|
+
msg = msg.to_s
|
|
7
|
+
re = /([A-Z_]+) ({.*})$/
|
|
8
|
+
msg_split = re.match(msg)
|
|
9
|
+
if msg_split.nil?
|
|
10
|
+
re = /^([A-Z_]+)$/
|
|
11
|
+
msg_split = re.match(msg)
|
|
12
|
+
raise "Error: Malformed Message" if not msg_split
|
|
13
|
+
type = msg_split[1]
|
|
14
|
+
data = {}
|
|
15
|
+
else
|
|
16
|
+
type = msg_split[1]
|
|
17
|
+
data = JSON.parse(msg_split[2])
|
|
18
|
+
end
|
|
19
|
+
{type: type, data: data}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Sends a message of a specific type
|
|
23
|
+
def send_message(type, message=nil)
|
|
24
|
+
message = message.nil? ? message = '' : message.to_json
|
|
25
|
+
body = type + ' ' + message
|
|
26
|
+
body.strip!
|
|
27
|
+
length = body.bytesize
|
|
28
|
+
@client.write("#{length}\n#{body}")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def update_dependencies(deps)
|
|
32
|
+
deps.each do |capability, instance|
|
|
33
|
+
@dependencies[capability] ||= {}
|
|
34
|
+
instance.each do |app_id, status|
|
|
35
|
+
@dependencies[capability][app_id] = status
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'securerandom'
|
|
3
|
+
require 'socket'
|
|
4
|
+
|
|
5
|
+
module Mycroft
|
|
6
|
+
module Messages
|
|
7
|
+
include Helpers
|
|
8
|
+
|
|
9
|
+
# connects to mycroft aka starts tls if necessary
|
|
10
|
+
def connect_to_mycroft
|
|
11
|
+
if ARGV.length == 1 and ARGV[0] == '--no-tls'
|
|
12
|
+
@client = TCPSocket.open(@host, @port)
|
|
13
|
+
else
|
|
14
|
+
socket = TCPSocket.new(@host, @port)
|
|
15
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
|
16
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new(File.open(@cert))
|
|
17
|
+
ssl_context.key = OpenSSL::PKey::RSA.new(File.open(@key))
|
|
18
|
+
@client = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
|
|
19
|
+
begin
|
|
20
|
+
@client.connect
|
|
21
|
+
rescue
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Sends the app manifest to mycroft
|
|
27
|
+
def send_manifest
|
|
28
|
+
begin
|
|
29
|
+
manifest = JSON.parse(File.read(@manifest))
|
|
30
|
+
manifest['instanceId'] = "#{Socket.gethostname}_#{SecureRandom.uuid}" if @generate_instance_ids
|
|
31
|
+
@instance_id = manifest['instanceId']
|
|
32
|
+
rescue
|
|
33
|
+
end
|
|
34
|
+
send_message('APP_MANIFEST', manifest)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Sends app up to mycroft
|
|
38
|
+
def up
|
|
39
|
+
send_message('APP_UP')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Sends app down to mycroft
|
|
43
|
+
def down
|
|
44
|
+
send_message('APP_DOWN')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def in_use(priority)
|
|
48
|
+
send_message('APP_IN_USE', {priority: (priority or 30)})
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Sends a query to mycroft
|
|
52
|
+
def query(capability, action, data, priority = 30, instance_id = nil)
|
|
53
|
+
query_message = {
|
|
54
|
+
id: SecureRandom.uuid,
|
|
55
|
+
capability: capability,
|
|
56
|
+
action: action,
|
|
57
|
+
data: data,
|
|
58
|
+
priority: priority,
|
|
59
|
+
instanceId: []
|
|
60
|
+
}
|
|
61
|
+
query_message[:instanceId] = instance_id unless instance_id.nil?
|
|
62
|
+
|
|
63
|
+
send_message('MSG_QUERY', query_message)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def query_success(id, ret)
|
|
67
|
+
query_success_message = {
|
|
68
|
+
id: id,
|
|
69
|
+
ret: ret
|
|
70
|
+
}
|
|
71
|
+
send_message('MSG_QUERY_SUCCESS', query_success_message)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def query_fail(id, message)
|
|
75
|
+
query_fail_message = {
|
|
76
|
+
id: id,
|
|
77
|
+
message: message
|
|
78
|
+
}
|
|
79
|
+
send_message('MSG_QUERY_FAIL', query_fail_message)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Sends a broadcast to the mycroft message board
|
|
83
|
+
def broadcast(content)
|
|
84
|
+
message = {
|
|
85
|
+
id: SecureRandom.uuid,
|
|
86
|
+
content: content
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
send_message('MSG_BROADCAST', message)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'mycroft'
|
|
2
|
+
|
|
3
|
+
class %%APPNAME%% < Mycroft::Client
|
|
4
|
+
|
|
5
|
+
def initialize(host, port)
|
|
6
|
+
@key = '/path/to/key'
|
|
7
|
+
@cert = '/path/to/cert'
|
|
8
|
+
@manifest = './app.json'
|
|
9
|
+
@verified = false
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
on 'APP_DEPENDENCY' do |data|
|
|
14
|
+
# Your code here
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Any other event handlers
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Mycroft.start(%%APPNAME%%)
|
data/mycroft.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'mycroft/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "mycroft"
|
|
8
|
+
spec.version = Mycroft::VERSION
|
|
9
|
+
spec.authors = ["rit-sse"]
|
|
10
|
+
spec.description = %q{Gem for creating a mycroft app in ruby.}
|
|
11
|
+
spec.summary = %q{Gem for creating a mycroft app in ruby.}
|
|
12
|
+
spec.homepage = "https://github.com/rit-sse-mycroft/template-ruby"
|
|
13
|
+
spec.license = "BSD"
|
|
14
|
+
|
|
15
|
+
spec.files = `git ls-files`.split($/)
|
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
|
+
spec.require_paths = ["lib"]
|
|
19
|
+
|
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
21
|
+
spec.add_development_dependency "rake"
|
|
22
|
+
spec.add_development_dependency "rspec"
|
|
23
|
+
spec.add_runtime_dependency "thor"
|
|
24
|
+
spec.add_runtime_dependency "activesupport"
|
|
25
|
+
spec.add_runtime_dependency "i18n"
|
|
26
|
+
spec.add_runtime_dependency "colorize"
|
|
27
|
+
spec.add_runtime_dependency "highline"
|
|
28
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
describe Mycroft::Helpers do
|
|
5
|
+
let(:client) {Mycroft::MockMycroftClient.new}
|
|
6
|
+
context 'message parsing' do
|
|
7
|
+
it 'should parse messages with a body' do
|
|
8
|
+
message = 'MSG_QUERY {"something": "something else"}'
|
|
9
|
+
hash = client.parse_message(message)
|
|
10
|
+
expect(hash).to eql({type: 'MSG_QUERY', data: {'something' => 'something else'}})
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should parse messages without a body' do
|
|
14
|
+
message = 'APP_UP'
|
|
15
|
+
hash = client.parse_message(message)
|
|
16
|
+
expect(hash).to eql({type: 'APP_UP', data: {}})
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'malformed message' do
|
|
20
|
+
it 'should raise error for backwards message' do
|
|
21
|
+
message = '{"something": "something else"} MSG_QUERY'
|
|
22
|
+
expect{ client.parse_message(message) }.to raise_error
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should raise an error for just a json object' do
|
|
26
|
+
message = '{"something": "something else"}'
|
|
27
|
+
expect{ client.parse_message(message) }.to raise_error
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'should raise an error for empty string' do
|
|
31
|
+
expect{ client.parse_message('') }.to raise_error
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context 'sending messages' do
|
|
37
|
+
it 'will send message with a body' do
|
|
38
|
+
client.send_message('MSG_QUERY',{something: 'something else'})
|
|
39
|
+
expect(client.server.read).to eql({size: 40, message: 'MSG_QUERY {"something":"something else"}'})
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'will send message without a body' do
|
|
43
|
+
client.send_message('APP_UP')
|
|
44
|
+
expect(client.server.read).to eql({size: 6, message: 'APP_UP'})
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context 'updating dependencies' do
|
|
49
|
+
it 'will update dependencies without existing dependencies' do
|
|
50
|
+
deps = {'stt' => {'stt1' => 'up', 'stt2' => 'down'}, 'logger' => {'logger1' => 'up', 'logger2' => 'down'}}
|
|
51
|
+
client.update_dependencies(deps)
|
|
52
|
+
expect(client.dependencies).to eql(deps)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'will update dependencies with existing dependencies'do
|
|
56
|
+
client.dependencies = {'stt' => {'stt1' => 'up', 'stt2' => 'down'}, 'logger' => {'logger1' => 'up', 'logger2' => 'down'}}
|
|
57
|
+
client.update_dependencies({'stt' => {'stt1' => 'down'}})
|
|
58
|
+
client.update_dependencies({'tts' => {'tts1' => 'up'}})
|
|
59
|
+
new_deps = {'stt' => {'stt1' => 'down', 'stt2' => 'down'}, 'logger' => {'logger1' => 'up', 'logger2' => 'down'}, 'tts' => {'tts1' => 'up'}}
|
|
60
|
+
expect(client.dependencies).to eql(new_deps)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/spec/mock.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'stringio'
|
|
2
|
+
module Mycroft
|
|
3
|
+
class MockClient
|
|
4
|
+
def initialize(server)
|
|
5
|
+
@server = server
|
|
6
|
+
end
|
|
7
|
+
def write(bytes)
|
|
8
|
+
@server.stream.write(bytes)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class MockServer
|
|
13
|
+
attr_reader :stream
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@stream = StringIO.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def read
|
|
20
|
+
@stream.rewind
|
|
21
|
+
size = @stream.readline
|
|
22
|
+
message = @stream.read(size.to_i)
|
|
23
|
+
{size: size.to_i, message: message}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class MockMycroftClient
|
|
28
|
+
include Messages
|
|
29
|
+
|
|
30
|
+
attr_accessor :server, :dependencies
|
|
31
|
+
|
|
32
|
+
def initialize
|
|
33
|
+
@dependencies = {}
|
|
34
|
+
@server = MockServer.new
|
|
35
|
+
@client = MockClient.new(@server)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mycroft
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- rit-sse
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2014-04-01 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: bundler
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ~>
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '1.3'
|
|
22
|
+
type: :development
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '1.3'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: rake
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ! '>='
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
38
|
+
type: :development
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ! '>='
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '0'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: rspec
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ! '>='
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ! '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
- !ruby/object:Gem::Dependency
|
|
63
|
+
name: thor
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
66
|
+
requirements:
|
|
67
|
+
- - ! '>='
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
type: :runtime
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
78
|
+
- !ruby/object:Gem::Dependency
|
|
79
|
+
name: activesupport
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
82
|
+
requirements:
|
|
83
|
+
- - ! '>='
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
86
|
+
type: :runtime
|
|
87
|
+
prerelease: false
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ! '>='
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
94
|
+
- !ruby/object:Gem::Dependency
|
|
95
|
+
name: i18n
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
97
|
+
none: false
|
|
98
|
+
requirements:
|
|
99
|
+
- - ! '>='
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '0'
|
|
102
|
+
type: :runtime
|
|
103
|
+
prerelease: false
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ! '>='
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: colorize
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
none: false
|
|
114
|
+
requirements:
|
|
115
|
+
- - ! '>='
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :runtime
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
none: false
|
|
122
|
+
requirements:
|
|
123
|
+
- - ! '>='
|
|
124
|
+
- !ruby/object:Gem::Version
|
|
125
|
+
version: '0'
|
|
126
|
+
- !ruby/object:Gem::Dependency
|
|
127
|
+
name: highline
|
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
|
129
|
+
none: false
|
|
130
|
+
requirements:
|
|
131
|
+
- - ! '>='
|
|
132
|
+
- !ruby/object:Gem::Version
|
|
133
|
+
version: '0'
|
|
134
|
+
type: :runtime
|
|
135
|
+
prerelease: false
|
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
137
|
+
none: false
|
|
138
|
+
requirements:
|
|
139
|
+
- - ! '>='
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: '0'
|
|
142
|
+
description: Gem for creating a mycroft app in ruby.
|
|
143
|
+
email:
|
|
144
|
+
executables:
|
|
145
|
+
- mycroft-ruby
|
|
146
|
+
extensions: []
|
|
147
|
+
extra_rdoc_files: []
|
|
148
|
+
files:
|
|
149
|
+
- .gitignore
|
|
150
|
+
- Gemfile
|
|
151
|
+
- LICENSE
|
|
152
|
+
- README.md
|
|
153
|
+
- Rakefile
|
|
154
|
+
- bin/mycroft-ruby
|
|
155
|
+
- lib/mycroft.rb
|
|
156
|
+
- lib/mycroft/cli.rb
|
|
157
|
+
- lib/mycroft/client.rb
|
|
158
|
+
- lib/mycroft/helpers.rb
|
|
159
|
+
- lib/mycroft/messages.rb
|
|
160
|
+
- lib/mycroft/templates/app_manifest
|
|
161
|
+
- lib/mycroft/templates/app_template
|
|
162
|
+
- lib/mycroft/version.rb
|
|
163
|
+
- mycroft.gemspec
|
|
164
|
+
- spec/helpers_spec.rb
|
|
165
|
+
- spec/mock.rb
|
|
166
|
+
- spec/spec_helper.rb
|
|
167
|
+
homepage: https://github.com/rit-sse-mycroft/template-ruby
|
|
168
|
+
licenses:
|
|
169
|
+
- BSD
|
|
170
|
+
post_install_message:
|
|
171
|
+
rdoc_options: []
|
|
172
|
+
require_paths:
|
|
173
|
+
- lib
|
|
174
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
175
|
+
none: false
|
|
176
|
+
requirements:
|
|
177
|
+
- - ! '>='
|
|
178
|
+
- !ruby/object:Gem::Version
|
|
179
|
+
version: '0'
|
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
181
|
+
none: false
|
|
182
|
+
requirements:
|
|
183
|
+
- - ! '>='
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: '0'
|
|
186
|
+
requirements: []
|
|
187
|
+
rubyforge_project:
|
|
188
|
+
rubygems_version: 1.8.28
|
|
189
|
+
signing_key:
|
|
190
|
+
specification_version: 3
|
|
191
|
+
summary: Gem for creating a mycroft app in ruby.
|
|
192
|
+
test_files:
|
|
193
|
+
- spec/helpers_spec.rb
|
|
194
|
+
- spec/mock.rb
|
|
195
|
+
- spec/spec_helper.rb
|