nodus 0.3.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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +38 -0
- data/LICENSE.txt +20 -0
- data/OPERUM.md +8 -0
- data/README.md +383 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/dia.rb +29 -0
- data/doc/desc.md +191 -0
- data/doc/example.node +89 -0
- data/doc/nodes.rb +77 -0
- data/doc/pipe.svg +97 -0
- data/doc/pipe.txt +4 -0
- data/doc/pipe2.dot +49 -0
- data/doc/pipe2.svg +163 -0
- data/lib/VERSION +1 -0
- data/lib/extensions.rb +162 -0
- data/lib/flexhash.rb +175 -0
- data/lib/nodus.rb +77 -0
- data/lib/nodus/nodes.rb +160 -0
- data/lib/nodus/stream.rb +12 -0
- data/lib/nodus/token.rb +31 -0
- data/lib/nodus/version.rb +6 -0
- data/lib/proplist.rb +142 -0
- data/nodus.gemspec +106 -0
- data/spec.md +60 -0
- data/test/core/test_flexhash.rb +87 -0
- data/test/core/test_generator.rb +27 -0
- data/test/core/test_node.rb +103 -0
- data/test/core/test_proplist.rb +153 -0
- data/test/helper.rb +107 -0
- metadata +188 -0
@@ -0,0 +1,153 @@
|
|
1
|
+
require_relative '../helper.rb'
|
2
|
+
|
3
|
+
describe PropSet do
|
4
|
+
subject { PropSet.new(required: false, type: Fixnum, desc: 'does stuff', visible: true) }
|
5
|
+
|
6
|
+
class PropSetSub < PropSet
|
7
|
+
default weirdy: 'yes'
|
8
|
+
inverse visible: :hidden
|
9
|
+
inverse required: :optional
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:subclass){ PropSetSub.new(required: false, type: Numeric, visible: true) }
|
13
|
+
|
14
|
+
it 'initialization properties become methods' do
|
15
|
+
subject.required.must_be_false
|
16
|
+
subject.type.must_equal Fixnum
|
17
|
+
subject.desc.must_equal 'does stuff'
|
18
|
+
subject.visible.must_be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'allows adhoc additions to initialized properties' do
|
22
|
+
subject.type = ArgumentError
|
23
|
+
subject.type.must_equal ArgumentError
|
24
|
+
subject.desc.must_equal 'does stuff'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'allows queries to see if things are specified' do
|
28
|
+
subject.has_required?.must_be_true
|
29
|
+
subject.has_desc?.must_be_true
|
30
|
+
subject.has_default?.must_be_false
|
31
|
+
subject.default = 1234
|
32
|
+
subject.default.must_equal 1234
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'correctly emits values for reversed attributes' do
|
36
|
+
subclass.visible.must_be_true
|
37
|
+
subclass.hidden.must_be_false
|
38
|
+
subclass.required.must_be_false
|
39
|
+
subclass.optional.must_be_true
|
40
|
+
|
41
|
+
subclass.required = true
|
42
|
+
subclass.optional.must_be_false
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'correctly emits values for bool attribute methods' do
|
46
|
+
subclass.visible?.must_be_true
|
47
|
+
subclass.required?.must_be_false
|
48
|
+
subclass.optional?.must_be_true
|
49
|
+
subclass.type?.must_be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'allows removal of attributes completely' do
|
53
|
+
subclass.has_required?.must_be_true
|
54
|
+
subclass.no_required = true
|
55
|
+
subclass.has_required?.must_be_false
|
56
|
+
subclass.required.must_be_nil
|
57
|
+
subclass.optional.must_be_nil
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not confuse absent with nil-valued' do
|
61
|
+
subclass.has_sometimes_nil?.must_be_false
|
62
|
+
subclass.sometimes_nil.must_be_nil
|
63
|
+
subclass.sometimes_nil = nil
|
64
|
+
subclass.has_sometimes_nil?.must_be_true
|
65
|
+
subclass.sometimes_nil.must_be_nil
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'honors default values (and with reverses)' do
|
69
|
+
subclass.has_weirdy?.must_be_false
|
70
|
+
subclass.weirdy.must_equal 'yes'
|
71
|
+
|
72
|
+
subclass.weirdy = 'yes'
|
73
|
+
subclass.has_weirdy?.must_be_true
|
74
|
+
subclass.weirdy.must_equal 'yes'
|
75
|
+
|
76
|
+
subclass.no_weirdy = true
|
77
|
+
subclass.has_weirdy?.must_be_false
|
78
|
+
subclass.weirdy.must_equal 'yes'
|
79
|
+
subclass.weirdy?.must_be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
# TODO: check defaults on both keys of inverse pairs
|
83
|
+
# TODO: test `realize` and overridden versions
|
84
|
+
end
|
85
|
+
|
86
|
+
describe PropList do
|
87
|
+
class MyPropSet < PropSet
|
88
|
+
default blah: 20
|
89
|
+
default visible: true
|
90
|
+
default required: false
|
91
|
+
inverse required: :optional
|
92
|
+
inverse visible: :hidden
|
93
|
+
def realize(val)
|
94
|
+
self.value = val
|
95
|
+
self.no_blah = true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
subject { PropList.new(MyPropSet) }
|
100
|
+
|
101
|
+
it 'sees default correctly' do
|
102
|
+
b = MyPropSet.new({required: true, default: 900}, {name: :some_property})
|
103
|
+
b.required.must_be_true
|
104
|
+
b.default.must_equal 900
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'can be populated an element at a time' do
|
108
|
+
subject.add 'some_property', required: true, default: 900
|
109
|
+
subject.add :another, :optional, :hidden
|
110
|
+
subject.some_property.optional?.must_be_false
|
111
|
+
subject[:some_property].default.must_equal 900
|
112
|
+
subject.another.optional?.must_be_true
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'can query for elements using a shorthand method' do
|
116
|
+
subject.add 'some_property', required: true, default: 900
|
117
|
+
subject.add :another, :optional, :hidden
|
118
|
+
subject.must_respond_to :has_another?
|
119
|
+
subject.has_blahblah?.must_be_false
|
120
|
+
subject.has_some_property?.must_be_true
|
121
|
+
subject.has_another?.must_be_true
|
122
|
+
|
123
|
+
subject.include?('another').must_be_true
|
124
|
+
subject.includes?(:some_property).must_be_true
|
125
|
+
subject.includes?(:blahblahblah).must_be_false
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'can be populated using the << method' do
|
129
|
+
subject << [:first_property, :required, {default: 100}]
|
130
|
+
subject.first_property.optional?.must_be_false
|
131
|
+
subject.first_property.default.must_equal 100
|
132
|
+
subject.first_property.has_default?.must_be_true
|
133
|
+
subject.first_property.blah.must_equal 20
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'can be turned into a hash' do
|
137
|
+
subject.add 'some_property', required: true, default: 900
|
138
|
+
subject.add :another, :optional, :hidden
|
139
|
+
subject.to_hash.must_be_kind_of Hash
|
140
|
+
subject.to_hash.has_key?(:some_property).must_be_true
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'allows properties to become realized' do
|
144
|
+
subject.add 'prop1', :required, :visible
|
145
|
+
subject.add 'prop2', blah: 199, default: 100
|
146
|
+
|
147
|
+
subject.prop1.value.must_be_nil
|
148
|
+
subject.prop1.blah.must_equal 20
|
149
|
+
subject.realize(:prop1, 500)
|
150
|
+
subject.prop1.value.must_equal 500
|
151
|
+
subject.prop1.has_blah?.must_be_false
|
152
|
+
end
|
153
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'simplecov'
|
11
|
+
require 'ffaker'
|
12
|
+
require 'randexp'
|
13
|
+
require 'minitest'
|
14
|
+
require 'minitest/reporters'
|
15
|
+
require 'minitest/spec'
|
16
|
+
require 'minitest/autorun'
|
17
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
18
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
19
|
+
require 'nodus'
|
20
|
+
|
21
|
+
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
22
|
+
|
23
|
+
module SimpleCov::Configuration
|
24
|
+
def clean_filters
|
25
|
+
@filters = []
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
SimpleCov.configure do
|
30
|
+
clean_filters
|
31
|
+
load_adapter 'test_frameworks'
|
32
|
+
end
|
33
|
+
|
34
|
+
ENV["COVERAGE"] && SimpleCov.start do
|
35
|
+
add_filter "/.rvm/"
|
36
|
+
end
|
37
|
+
I18n.enforce_available_locales = false
|
38
|
+
|
39
|
+
include Faker
|
40
|
+
|
41
|
+
|
42
|
+
module RandomGen
|
43
|
+
def rand_poisson(lmbda=10)
|
44
|
+
# Poisson distribution with mean & variance of lmda- via knuth's simple algorithm
|
45
|
+
el = Math.exp(- lmbda); k=0; p=1
|
46
|
+
loop do
|
47
|
+
k += 1; p *= rand
|
48
|
+
return k - 1 if p <= el
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def rand_times(lmbda=10, &block)
|
53
|
+
k = rand_poisson(lmbda)
|
54
|
+
if block_given? then k.times.map(&block)
|
55
|
+
else k.times end
|
56
|
+
end
|
57
|
+
|
58
|
+
def rand_word
|
59
|
+
len = rand_poisson
|
60
|
+
return '' if len == 0
|
61
|
+
/\w{#{len}}/.gen
|
62
|
+
end
|
63
|
+
|
64
|
+
def random_path
|
65
|
+
'/' + rand_times{rand_word}.join('/')
|
66
|
+
end
|
67
|
+
|
68
|
+
def random_datetime
|
69
|
+
::Faker::Time.date(series: [])[0]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
include RandomGen
|
74
|
+
|
75
|
+
class Module
|
76
|
+
include Minitest::Spec::DSL
|
77
|
+
end
|
78
|
+
|
79
|
+
def remove_class(klass)
|
80
|
+
const = klass.to_s.to_sym
|
81
|
+
Object.send(:remove_const, const) if Object.send(:const_defined?, const)
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
module MiniTest::Assertions
|
86
|
+
def assert_true(obj) assert obj==true, "expected '#{obj}' to be true" end
|
87
|
+
def assert_false(obj) assert obj==false, "expected '#{obj}' to be false" end
|
88
|
+
def assert_truthy(obj) assert obj, "expected '#{obj}' to be something other than nil or false" end
|
89
|
+
def assert_falsy(obj) refute obj, "expected '#{obj}' to be nil or false" end
|
90
|
+
end
|
91
|
+
Object.infect_an_assertion :assert_true, :must_be_true, :only_one_argument
|
92
|
+
Object.infect_an_assertion :assert_false, :must_be_false, :only_one_argument
|
93
|
+
Object.infect_an_assertion :assert_truthy, :must_be_truthy, :only_one_argument
|
94
|
+
Object.infect_an_assertion :assert_falsy, :must_be_falsy, :only_one_argument
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
#----------------------------------- NODUS SPECIFIC ---------------------------------------------------------
|
99
|
+
|
100
|
+
module MiniTest::Assertions
|
101
|
+
def assert_kind_of_node(obj)
|
102
|
+
assert obj.kind_of_node?, "expected #{obj} to be a class descended from Node"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
Object.infect_an_assertion :assert_kind_of_node,
|
106
|
+
:must_be_a_node,
|
107
|
+
:only_one_argument
|
metadata
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nodus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joseph Wecker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2014-07-31 00:00:00 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
type: :runtime
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ">="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 4.1.0
|
22
|
+
version_requirements: *id001
|
23
|
+
prerelease: false
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: bundler
|
26
|
+
type: :development
|
27
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- &id003
|
30
|
+
- ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: "0"
|
33
|
+
version_requirements: *id002
|
34
|
+
prerelease: false
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: git
|
37
|
+
type: :development
|
38
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- *id003
|
41
|
+
version_requirements: *id004
|
42
|
+
prerelease: false
|
43
|
+
- !ruby/object:Gem::Dependency
|
44
|
+
name: jeweler
|
45
|
+
type: :development
|
46
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- *id003
|
49
|
+
version_requirements: *id005
|
50
|
+
prerelease: false
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: brice
|
53
|
+
type: :development
|
54
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- *id003
|
57
|
+
version_requirements: *id006
|
58
|
+
prerelease: false
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: ansi
|
61
|
+
type: :development
|
62
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- *id003
|
65
|
+
version_requirements: *id007
|
66
|
+
prerelease: false
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rdoc
|
69
|
+
type: :development
|
70
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- *id003
|
73
|
+
version_requirements: *id008
|
74
|
+
prerelease: false
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: ffaker
|
77
|
+
type: :development
|
78
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- *id003
|
81
|
+
version_requirements: *id009
|
82
|
+
prerelease: false
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: randexp
|
85
|
+
type: :development
|
86
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- *id003
|
89
|
+
version_requirements: *id010
|
90
|
+
prerelease: false
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: minitest
|
93
|
+
type: :development
|
94
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: "5.3"
|
99
|
+
version_requirements: *id011
|
100
|
+
prerelease: false
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: minitest-reporters
|
103
|
+
type: :development
|
104
|
+
requirement: &id012 !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 1.0.1
|
109
|
+
version_requirements: *id012
|
110
|
+
prerelease: false
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
type: :development
|
114
|
+
requirement: &id013 !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ~>
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 0.7.1
|
119
|
+
version_requirements: *id013
|
120
|
+
prerelease: false
|
121
|
+
description: EXPERIMENTAL. A form of data-flow programming based loosely on Kahn Process Networks. Will allow for setting up operational components that can be pipelined together in a graph. Assumes all components (nodes) are 'online' algorithms with more or less steady-state resource utilization for continuous streams of data.
|
122
|
+
email: joseph.wecker@exsig.com
|
123
|
+
executables: []
|
124
|
+
|
125
|
+
extensions: []
|
126
|
+
|
127
|
+
extra_rdoc_files:
|
128
|
+
- LICENSE.txt
|
129
|
+
- README.md
|
130
|
+
files:
|
131
|
+
- .document
|
132
|
+
- .ruby-gemset
|
133
|
+
- .ruby-version
|
134
|
+
- Gemfile
|
135
|
+
- LICENSE.txt
|
136
|
+
- OPERUM.md
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- VERSION
|
140
|
+
- dia.rb
|
141
|
+
- doc/desc.md
|
142
|
+
- doc/example.node
|
143
|
+
- doc/nodes.rb
|
144
|
+
- doc/pipe.svg
|
145
|
+
- doc/pipe.txt
|
146
|
+
- doc/pipe2.dot
|
147
|
+
- doc/pipe2.svg
|
148
|
+
- lib/VERSION
|
149
|
+
- lib/extensions.rb
|
150
|
+
- lib/flexhash.rb
|
151
|
+
- lib/nodus.rb
|
152
|
+
- lib/nodus/nodes.rb
|
153
|
+
- lib/nodus/stream.rb
|
154
|
+
- lib/nodus/token.rb
|
155
|
+
- lib/nodus/version.rb
|
156
|
+
- lib/proplist.rb
|
157
|
+
- nodus.gemspec
|
158
|
+
- spec.md
|
159
|
+
- test/core/test_flexhash.rb
|
160
|
+
- test/core/test_generator.rb
|
161
|
+
- test/core/test_node.rb
|
162
|
+
- test/core/test_proplist.rb
|
163
|
+
- test/helper.rb
|
164
|
+
homepage: http://github.com/exsig/nodus
|
165
|
+
licenses:
|
166
|
+
- MIT
|
167
|
+
metadata: {}
|
168
|
+
|
169
|
+
post_install_message:
|
170
|
+
rdoc_options: []
|
171
|
+
|
172
|
+
require_paths:
|
173
|
+
- lib
|
174
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- *id003
|
177
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- *id003
|
180
|
+
requirements: []
|
181
|
+
|
182
|
+
rubyforge_project:
|
183
|
+
rubygems_version: 2.2.2
|
184
|
+
signing_key:
|
185
|
+
specification_version: 4
|
186
|
+
summary: Something between a Kahn Process Network and Algorithmic Skeleton for parallel pipelining and signal processing
|
187
|
+
test_files: []
|
188
|
+
|