patch 0.4.13
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.
- checksums.yaml +7 -0
- data/LICENSE +13 -0
- data/README.md +176 -0
- data/bin/patchrb +40 -0
- data/lib/patch/config.rb +124 -0
- data/lib/patch/em_patch.rb +47 -0
- data/lib/patch/hub.rb +68 -0
- data/lib/patch/io/midi/action.rb +42 -0
- data/lib/patch/io/midi/input.rb +110 -0
- data/lib/patch/io/midi/message.rb +112 -0
- data/lib/patch/io/midi/output.rb +58 -0
- data/lib/patch/io/midi.rb +45 -0
- data/lib/patch/io/module.rb +35 -0
- data/lib/patch/io/osc/action.rb +43 -0
- data/lib/patch/io/osc/client.rb +60 -0
- data/lib/patch/io/osc/message.rb +109 -0
- data/lib/patch/io/osc/server.rb +159 -0
- data/lib/patch/io/osc.rb +43 -0
- data/lib/patch/io/websocket/node.rb +103 -0
- data/lib/patch/io/websocket/socket.rb +103 -0
- data/lib/patch/io/websocket.rb +27 -0
- data/lib/patch/io.rb +15 -0
- data/lib/patch/log.rb +97 -0
- data/lib/patch/message.rb +67 -0
- data/lib/patch/node/container.rb +69 -0
- data/lib/patch/node/map.rb +71 -0
- data/lib/patch/node.rb +10 -0
- data/lib/patch/patch.rb +59 -0
- data/lib/patch/report.rb +132 -0
- data/lib/patch/thread.rb +19 -0
- data/lib/patch.rb +42 -0
- data/test/config/nodes.yml +16 -0
- data/test/config/patches.yml +41 -0
- data/test/config_test.rb +216 -0
- data/test/helper.rb +20 -0
- data/test/hub_test.rb +49 -0
- data/test/io/midi/action_test.rb +82 -0
- data/test/io/midi/input_test.rb +130 -0
- data/test/io/midi/message_test.rb +54 -0
- data/test/io/midi/output_test.rb +44 -0
- data/test/io/midi_test.rb +94 -0
- data/test/io/module_test.rb +21 -0
- data/test/io/osc/action_test.rb +76 -0
- data/test/io/osc/client_test.rb +49 -0
- data/test/io/osc/message_test.rb +53 -0
- data/test/io/osc/server_test.rb +116 -0
- data/test/io/osc_test.rb +111 -0
- data/test/io/websocket/node_test.rb +96 -0
- data/test/io/websocket_test.rb +37 -0
- data/test/js/logger.js +67 -0
- data/test/js/message.js +62 -0
- data/test/js/qunit-1.18.0.js +3828 -0
- data/test/js/qunit.css +291 -0
- data/test/js/test.html +15 -0
- data/test/js/websocket.js +12 -0
- data/test/log_test.rb +96 -0
- data/test/message_test.rb +109 -0
- data/test/node/container_test.rb +104 -0
- data/test/node/map_test.rb +50 -0
- data/test/node_test.rb +14 -0
- data/test/patch_test.rb +57 -0
- data/test/report_test.rb +37 -0
- metadata +320 -0
data/lib/patch/report.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
module Patch
|
2
|
+
|
3
|
+
# Terminal/Console output explaining the hub configuration
|
4
|
+
class Report
|
5
|
+
|
6
|
+
# @param [Hub] hub The hub to print a report for
|
7
|
+
# @return [Report]
|
8
|
+
def self.print(hub)
|
9
|
+
new(hub).print
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [Hub] hub The hub to report about
|
13
|
+
def initialize(hub)
|
14
|
+
@hub = hub
|
15
|
+
end
|
16
|
+
|
17
|
+
# Print a report to standard out
|
18
|
+
# @return [Report] self
|
19
|
+
def print
|
20
|
+
report = self.report
|
21
|
+
puts
|
22
|
+
print_logo
|
23
|
+
puts
|
24
|
+
puts Rainbow("IPs").cyan
|
25
|
+
puts Rainbow("———").cyan
|
26
|
+
report[:ips].each { |ip| puts ip }
|
27
|
+
puts
|
28
|
+
puts Rainbow("Nodes").cyan
|
29
|
+
puts Rainbow("———").cyan
|
30
|
+
report[:nodes].each do |node|
|
31
|
+
puts "#{node[:id]}: #{node[:name]}"
|
32
|
+
end
|
33
|
+
puts
|
34
|
+
if report[:patches].count > 0
|
35
|
+
puts Rainbow("Patches").cyan
|
36
|
+
puts Rainbow("———").cyan
|
37
|
+
report[:patches].each_with_index do |patch, i|
|
38
|
+
puts "#{i+1}. #{patch[:name]}"
|
39
|
+
puts Rainbow("|").cyan
|
40
|
+
puts Rainbow("| Node Map").cyan
|
41
|
+
puts Rainbow("| ———").cyan
|
42
|
+
patch[:maps].each { |map| puts Rainbow("| ").cyan + map }
|
43
|
+
puts Rainbow("|").cyan
|
44
|
+
puts Rainbow("| Actions").cyan
|
45
|
+
puts Rainbow("| ———").cyan
|
46
|
+
chunked_actions(patch[:actions]).each do |chunk|
|
47
|
+
puts Rainbow("| ").cyan + chunk
|
48
|
+
end
|
49
|
+
puts Rainbow("|").cyan
|
50
|
+
puts
|
51
|
+
end
|
52
|
+
else
|
53
|
+
puts
|
54
|
+
end
|
55
|
+
unless report[:log].nil?
|
56
|
+
puts "Logging to #{report[:log]}"
|
57
|
+
puts
|
58
|
+
end
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
# Construct the report hash
|
63
|
+
# @return [Hash]
|
64
|
+
def report
|
65
|
+
report = {}
|
66
|
+
report[:ips] = @hub.ips
|
67
|
+
report[:nodes] = @hub.nodes.sort_by(&:id).map { |node| node_report(node) }
|
68
|
+
report[:patches] = @hub.patches.map { |patch| patch_report(patch) }
|
69
|
+
report[:log] = @hub.log.path unless @hub.log.nil?
|
70
|
+
report
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# Get a patch action formatted for terminal width
|
76
|
+
# @param [Array<String>] actions
|
77
|
+
# @return [Array<String>]
|
78
|
+
def chunked_actions(actions)
|
79
|
+
max_length = columns - 10
|
80
|
+
chunks = []
|
81
|
+
actions.each do |action|
|
82
|
+
if chunks.last.nil? || chunks.last.length >= max_length - action.length
|
83
|
+
chunks << ""
|
84
|
+
end
|
85
|
+
chunk = chunks.last
|
86
|
+
chunk << "#{action}"
|
87
|
+
chunk << ", " unless action == actions.last
|
88
|
+
end
|
89
|
+
chunks
|
90
|
+
end
|
91
|
+
|
92
|
+
# The number of columns of the terminal
|
93
|
+
# @return [Fixnum]
|
94
|
+
def columns
|
95
|
+
`tput cols`.to_i rescue 80
|
96
|
+
end
|
97
|
+
|
98
|
+
# Output the patch logo
|
99
|
+
# @return [Boolean]
|
100
|
+
def print_logo
|
101
|
+
color = :blue
|
102
|
+
puts Rainbow("██████╗ █████╗ ████████╗ ██████╗██╗ ██╗").send(color)
|
103
|
+
puts Rainbow("██╔══██╗██╔══██╗╚══██╔══╝██╔════╝██║ ██║").send(color)
|
104
|
+
puts Rainbow("██████╔╝███████║ ██║ ██║ ███████║").send(color)
|
105
|
+
puts Rainbow("██╔═══╝ ██╔══██║ ██║ ██║ ██╔══██║").send(color)
|
106
|
+
puts Rainbow("██║ ██║ ██║ ██║ ╚██████╗██║ ██║").send(color)
|
107
|
+
puts Rainbow("╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╣").send(color)
|
108
|
+
puts Rainbow("═≡≡≡▓▓▓═════════════════════════════════╝").send(color)
|
109
|
+
true
|
110
|
+
end
|
111
|
+
|
112
|
+
# Construct the report about a node
|
113
|
+
# @return [Hash]
|
114
|
+
def node_report(node)
|
115
|
+
report = {}
|
116
|
+
report[:id] = node.id
|
117
|
+
report[:name] = node.class.name
|
118
|
+
report
|
119
|
+
end
|
120
|
+
|
121
|
+
# Construct the report about a patch
|
122
|
+
# @return [Hash]
|
123
|
+
def patch_report(patch)
|
124
|
+
report = {}
|
125
|
+
report[:name] = patch.name
|
126
|
+
report[:maps] = patch.maps.map { |map| "#{map.from.map(&:id)} => #{map.to.map(&:id)}" }
|
127
|
+
report[:actions] = patch.actions.map { |mapping| mapping[:name] }
|
128
|
+
report
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
data/lib/patch/thread.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Patch
|
2
|
+
|
3
|
+
module Thread
|
4
|
+
|
5
|
+
def self.new(&block)
|
6
|
+
thread = ::Thread.new do
|
7
|
+
begin
|
8
|
+
yield
|
9
|
+
rescue Exception => exception
|
10
|
+
::Thread.main.raise(exception)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
thread.abort_on_exception = true
|
14
|
+
thread
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/lib/patch.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Patch
|
2
|
+
# Controller message patching
|
3
|
+
#
|
4
|
+
# Ari Russo
|
5
|
+
# (c)2014-2015
|
6
|
+
# Licensed under Apache 2.0
|
7
|
+
#
|
8
|
+
|
9
|
+
# Libs
|
10
|
+
require "forwardable"
|
11
|
+
require "json"
|
12
|
+
require "socket"
|
13
|
+
require "yaml"
|
14
|
+
|
15
|
+
require "em-websocket"
|
16
|
+
require "midi-eye"
|
17
|
+
require "osc-ruby"
|
18
|
+
require "osc-ruby/em_server"
|
19
|
+
require "rainbow"
|
20
|
+
require "scale"
|
21
|
+
|
22
|
+
# Modules
|
23
|
+
require "patch/config"
|
24
|
+
require "patch/io"
|
25
|
+
require "patch/node"
|
26
|
+
require "patch/thread"
|
27
|
+
|
28
|
+
# Classes
|
29
|
+
require "patch/hub"
|
30
|
+
require "patch/log"
|
31
|
+
require "patch/message"
|
32
|
+
require "patch/patch"
|
33
|
+
require "patch/report"
|
34
|
+
|
35
|
+
# Patches
|
36
|
+
require "patch/em_patch"
|
37
|
+
|
38
|
+
module Patch
|
39
|
+
|
40
|
+
VERSION = "0.4.13"
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
:nodes:
|
2
|
+
- :id: 1
|
3
|
+
:type: websocket
|
4
|
+
:host: localhost
|
5
|
+
:port: 9006
|
6
|
+
- :id: 2
|
7
|
+
:type: midi
|
8
|
+
:direction: input
|
9
|
+
:name: Apple Inc. IAC Driver
|
10
|
+
- :id: 3
|
11
|
+
:type: osc
|
12
|
+
:server:
|
13
|
+
:port: 8000
|
14
|
+
:client:
|
15
|
+
:host: 192.168.1.118
|
16
|
+
:port: 9000
|
@@ -0,0 +1,41 @@
|
|
1
|
+
:patches:
|
2
|
+
:test_patch:
|
3
|
+
:node_map:
|
4
|
+
[2, 3]: 1
|
5
|
+
:actions:
|
6
|
+
- :name: Zoom
|
7
|
+
:key: zoom
|
8
|
+
:default:
|
9
|
+
:scale: !ruby/range 0.1..5.0
|
10
|
+
:midi:
|
11
|
+
:channel: 0
|
12
|
+
:index: 0
|
13
|
+
:osc:
|
14
|
+
:address: /1/rotaryA
|
15
|
+
:scale: !ruby/range 0..1.0
|
16
|
+
|
17
|
+
- :name: Contrast
|
18
|
+
:key: contrast
|
19
|
+
:default:
|
20
|
+
:scale: !ruby/range 0..5.0
|
21
|
+
:osc:
|
22
|
+
:address: /1/rotaryD
|
23
|
+
:scale: !ruby/range 0..1.0
|
24
|
+
|
25
|
+
- :name: Saturation
|
26
|
+
:key: saturation
|
27
|
+
:default:
|
28
|
+
:scale: !ruby/range 0..2.0
|
29
|
+
:osc:
|
30
|
+
:address: /faderM
|
31
|
+
:scale:
|
32
|
+
:osc: !ruby/range 0..1.0
|
33
|
+
|
34
|
+
- :name: Z Depth
|
35
|
+
:key: zDepth
|
36
|
+
:default:
|
37
|
+
:scale: !ruby/range 0..1000
|
38
|
+
:osc:
|
39
|
+
:address: /1/faderA
|
40
|
+
:scale:
|
41
|
+
:osc: !ruby/range 0..1.0
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class Patch::SpecTest < Minitest::Test
|
4
|
+
|
5
|
+
context "Spec" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
load_test_data
|
9
|
+
end
|
10
|
+
|
11
|
+
context ".to_hub" do
|
12
|
+
|
13
|
+
setup do
|
14
|
+
@hub = Patch::Config.to_hub(@nodes_path, :patches => @patches_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
should "have nodes" do
|
18
|
+
refute_nil @hub.nodes
|
19
|
+
end
|
20
|
+
|
21
|
+
should "have patches" do
|
22
|
+
refute_nil @hub.patches
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context ".to_nodes" do
|
28
|
+
|
29
|
+
context "from files" do
|
30
|
+
|
31
|
+
setup do
|
32
|
+
@nodes = Patch::Config.to_nodes(@nodes_file)
|
33
|
+
end
|
34
|
+
|
35
|
+
should "populate" do
|
36
|
+
refute_nil @nodes
|
37
|
+
assert @nodes.kind_of?(Patch::Node::Container)
|
38
|
+
refute_empty @nodes
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context "from strings" do
|
44
|
+
|
45
|
+
setup do
|
46
|
+
@nodes = Patch::Config.to_nodes(@nodes_path)
|
47
|
+
end
|
48
|
+
|
49
|
+
should "populate" do
|
50
|
+
refute_nil @nodes
|
51
|
+
assert @nodes.kind_of?(Patch::Node::Container)
|
52
|
+
refute_empty @nodes
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
context "from hashes" do
|
58
|
+
|
59
|
+
setup do
|
60
|
+
@nodes_hash = {
|
61
|
+
:nodes => [{
|
62
|
+
:type => "websocket",
|
63
|
+
:id => 1,
|
64
|
+
:host => "localhost",
|
65
|
+
:port =>9006
|
66
|
+
}]
|
67
|
+
}
|
68
|
+
@nodes = Patch::Config.to_nodes(@nodes_hash)
|
69
|
+
end
|
70
|
+
|
71
|
+
should "populate" do
|
72
|
+
refute_nil @nodes
|
73
|
+
assert @nodes.kind_of?(Patch::Node::Container)
|
74
|
+
refute_empty @nodes
|
75
|
+
assert_equal @nodes_hash[:nodes].count, @nodes.count
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
context ".to_node_maps" do
|
81
|
+
|
82
|
+
setup do
|
83
|
+
@hash = YAML.load(File.new(@patches_path))
|
84
|
+
@nodes = Patch::Config.to_nodes(@nodes_file)
|
85
|
+
@map_config = @hash[:patches][:test_patch][:node_map]
|
86
|
+
end
|
87
|
+
|
88
|
+
should "instantiate maps" do
|
89
|
+
@maps = Patch::Config.to_node_maps(@nodes, @map_config)
|
90
|
+
refute_nil @maps
|
91
|
+
refute_empty @maps
|
92
|
+
assert_equal @map_config.size, @maps.size
|
93
|
+
assert @maps.first.kind_of?(Patch::Node::Map)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
context ".to_patches" do
|
99
|
+
|
100
|
+
setup do
|
101
|
+
@nodes = Patch::Config.to_nodes(@nodes_file)
|
102
|
+
@patches = Patch::Config.to_patches(@nodes, @patches_file)
|
103
|
+
end
|
104
|
+
|
105
|
+
should "create patches" do
|
106
|
+
refute_nil @patches
|
107
|
+
refute_empty @patches
|
108
|
+
assert @patches.first.kind_of?(Patch::Patch)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
context ".to_patch" do
|
114
|
+
|
115
|
+
setup do
|
116
|
+
@nodes = Patch::Config.to_nodes(@nodes_file)
|
117
|
+
config = {
|
118
|
+
:node_map => [{ [1,2] => 3 }],
|
119
|
+
:action => []
|
120
|
+
}
|
121
|
+
@patch = Patch::Config.send(:to_patch, :test, @nodes, config)
|
122
|
+
end
|
123
|
+
|
124
|
+
should "create patch" do
|
125
|
+
refute_nil @patch
|
126
|
+
assert @patch.kind_of?(Patch::Patch)
|
127
|
+
refute_nil @patch.maps
|
128
|
+
refute_nil @patch.actions
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
context ".ensure_hash" do
|
134
|
+
|
135
|
+
setup do
|
136
|
+
@path = File.join(__dir__, "config/patches.yml")
|
137
|
+
@file = File.new(@path)
|
138
|
+
end
|
139
|
+
|
140
|
+
context "path" do
|
141
|
+
|
142
|
+
setup do
|
143
|
+
@config = Patch::Config.send(:ensure_hash, @path)
|
144
|
+
end
|
145
|
+
|
146
|
+
should "populate" do
|
147
|
+
refute_nil @config
|
148
|
+
refute_empty @config
|
149
|
+
assert_equal Hash, @config.class
|
150
|
+
assert_equal 1, @config.keys.count
|
151
|
+
end
|
152
|
+
|
153
|
+
should "deep freeze" do
|
154
|
+
assert @config.frozen?
|
155
|
+
assert @config[:patches].frozen?
|
156
|
+
assert @config[:patches][:test_patch].frozen?
|
157
|
+
assert @config[:patches][:test_patch][:node_map].frozen?
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
context "file" do
|
163
|
+
|
164
|
+
setup do
|
165
|
+
@config = Patch::Config.send(:ensure_hash, @file)
|
166
|
+
end
|
167
|
+
|
168
|
+
should "populate" do
|
169
|
+
refute_nil @config
|
170
|
+
refute_empty @config
|
171
|
+
assert_equal Hash, @config.class
|
172
|
+
assert_equal 1, @config.keys.count
|
173
|
+
end
|
174
|
+
|
175
|
+
should "deep freeze" do
|
176
|
+
assert @config.frozen?
|
177
|
+
assert @config[:patches].frozen?
|
178
|
+
assert @config[:patches][:test_patch].frozen?
|
179
|
+
assert @config[:patches][:test_patch][:node_map].frozen?
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
context "hash" do
|
185
|
+
|
186
|
+
setup do
|
187
|
+
@hash = {
|
188
|
+
:test => {
|
189
|
+
:node_map => [{ [1,2] => 3 }],
|
190
|
+
:action => []
|
191
|
+
}
|
192
|
+
}
|
193
|
+
@config = Patch::Config.send(:ensure_hash, @hash)
|
194
|
+
end
|
195
|
+
|
196
|
+
should "populate" do
|
197
|
+
refute_nil @config
|
198
|
+
refute_empty @config
|
199
|
+
assert_equal Hash, @config.class
|
200
|
+
assert_equal 1, @config.keys.count
|
201
|
+
end
|
202
|
+
|
203
|
+
should "deep freeze" do
|
204
|
+
assert @config.frozen?
|
205
|
+
assert @config[:test].frozen?
|
206
|
+
assert @config[:test][:node_map].frozen?
|
207
|
+
assert @config[:test][:action].frozen?
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.unshift(File.join("..", "lib"))
|
2
|
+
|
3
|
+
require "minitest/autorun"
|
4
|
+
require "mocha/test_unit"
|
5
|
+
require "shoulda-context"
|
6
|
+
|
7
|
+
require "patch"
|
8
|
+
|
9
|
+
UDPSocket.any_instance.stubs(:connect)
|
10
|
+
EventMachine.stubs(:open_datagram_socket).returns(true)
|
11
|
+
EventMachine.stubs(:open_udp_socket).returns(true)
|
12
|
+
EventMachine.stubs(:start_server).returns(true)
|
13
|
+
EventMachine.stubs(:start_tcp_server).returns(true)
|
14
|
+
|
15
|
+
def load_test_data
|
16
|
+
@nodes_path = File.join(__dir__,"/config/nodes.yml")
|
17
|
+
@nodes_file = File.new(@nodes_path)
|
18
|
+
@patches_path = File.join(__dir__,"config/patches.yml")
|
19
|
+
@patches_file = File.new(@patches_path)
|
20
|
+
end
|
data/test/hub_test.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class Patch::HubTest < Minitest::Test
|
4
|
+
|
5
|
+
context "Hub" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
load_test_data
|
9
|
+
@hub = Patch::Config.to_hub(@nodes_path, :patches => @patches_path)
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#ips" do
|
13
|
+
|
14
|
+
should "have ips array" do
|
15
|
+
refute_nil @hub.ips
|
16
|
+
refute_empty @hub.ips
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
context "#listen" do
|
22
|
+
|
23
|
+
should "start listeners and controller" do
|
24
|
+
@hub.patches.each { |patch| patch.expects(:enable).once }
|
25
|
+
@hub.nodes.each { |node| node.expects(:enable).once }
|
26
|
+
assert @hub.listen(:background => true)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context "#nodes" do
|
32
|
+
|
33
|
+
should "be populated" do
|
34
|
+
refute_nil @hub.nodes
|
35
|
+
end
|
36
|
+
|
37
|
+
should "have nodes" do
|
38
|
+
refute_empty @hub.nodes
|
39
|
+
end
|
40
|
+
|
41
|
+
should "be node container" do
|
42
|
+
assert_equal Patch::Node::Container, @hub.nodes.class
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class Patch::IO::MIDI::ActionTest < Minitest::Test
|
4
|
+
|
5
|
+
context "Action" do
|
6
|
+
|
7
|
+
setup do
|
8
|
+
@actions = [
|
9
|
+
{
|
10
|
+
:name=>"Volume",
|
11
|
+
:key=>"volume",
|
12
|
+
:default=> {
|
13
|
+
:scale=>0..2.0
|
14
|
+
},
|
15
|
+
:midi => {
|
16
|
+
:channel=>4,
|
17
|
+
:index=>7
|
18
|
+
},
|
19
|
+
:osc=> {
|
20
|
+
:address=>"/faderM",
|
21
|
+
:scale=> {
|
22
|
+
:osc=>0..1.0
|
23
|
+
}
|
24
|
+
}
|
25
|
+
},
|
26
|
+
{
|
27
|
+
:name=>"Z Depth",
|
28
|
+
:key=>"zDepth",
|
29
|
+
:default=>{
|
30
|
+
:scale=>0..1000
|
31
|
+
},
|
32
|
+
:osc=>{
|
33
|
+
:address=>"/1/faderA",
|
34
|
+
:scale=> {
|
35
|
+
:osc=>0..1.0
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
context "#midi_actions" do
|
43
|
+
|
44
|
+
should "return only midi actions" do
|
45
|
+
actions = Patch::IO::MIDI::Action.midi_actions(@actions)
|
46
|
+
refute_nil actions
|
47
|
+
refute_empty actions
|
48
|
+
assert_equal 1, actions.size
|
49
|
+
assert_equal @actions[0], actions.first
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
context "#midi?" do
|
55
|
+
|
56
|
+
should "return true for actions with midi" do
|
57
|
+
assert Patch::IO::MIDI::Action.midi?(@actions[0])
|
58
|
+
end
|
59
|
+
|
60
|
+
should "return false for actions without midi" do
|
61
|
+
refute Patch::IO::MIDI::Action.midi?(@actions[1])
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
context "#find_by_index" do
|
67
|
+
|
68
|
+
should "return action if it has midi" do
|
69
|
+
action = Patch::IO::MIDI::Action.find_by_index(@actions, 7)
|
70
|
+
refute_nil action
|
71
|
+
end
|
72
|
+
|
73
|
+
should "not return action if it doesn't have midi" do
|
74
|
+
action = Patch::IO::MIDI::Action.find_by_index(@actions, 1)
|
75
|
+
assert_nil action
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|