pacer-scale 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0ae24a6f4ae17b93d6b101672bd2d239a66fdef1
4
+ data.tar.gz: 57532b97c2689e75cf43079db59b96f6498d5038
5
+ SHA512:
6
+ metadata.gz: 48af340eab76ba9c58e157b4fd09e0729f50655f2c5bb93b76011e57645cb15247f482d87c3e32b85cc28c55bea8caacaa1bf2ba3de94a274dc0f254a8213d28
7
+ data.tar.gz: 29fa6867b7615aacaea03faf9ee5aac3e069042ac9e730e498c345b63ccb2f35d639bf10e6c54f65e23114e8f46561502040fb1b31025b8a4a5fdb89629c5bf9
data/Jarfile ADDED
@@ -0,0 +1,6 @@
1
+ repository "https://repo1.maven.org/maven2/"
2
+ repository "https://clojars.org/repo/"
3
+ jar "org.clojure:clojure:1.7.0-alpha6"
4
+ jar "com.tinkerpop.blueprints:blueprints-core:2.6.0"
5
+ jar "com.tinkerpop:pipes:2.6.0"
6
+ jar "com.tinkerpop.gremlin:gremlin-java:2.6.0"
@@ -0,0 +1,23 @@
1
+ $: << 'src/ruby'
2
+ require 'spec_helper'
3
+
4
+ describe 'simple rating scale' do
5
+ before do
6
+ @g = Pacer.tg
7
+ @root = @g.create_vertex(PacerScale::Root)
8
+ @root.generate_scale 'ranking', 1, 10, 1
9
+ end
10
+
11
+ it 'should find each valid ranking' do
12
+ v = @root.find 'ranking', 1
13
+ v.should_not be_nil
14
+ end
15
+
16
+ it 'should find each valid ranking' do
17
+ (1..10).each do |n|
18
+ v = @root.find 'ranking', n
19
+ v.should_not be_nil
20
+ v.value.should == n
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,76 @@
1
+ require 'pacer-scale'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
6
+ # this file to always be loaded, without a need to explicitly require it in any
7
+ # files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need
15
+ # it.
16
+ #
17
+ # The `.rspec` file also contains a few flags that are not defaults but that
18
+ # users commonly want.
19
+ #
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+ RSpec.configure do |config|
22
+ # rspec-expectations config goes here. You can use an alternate
23
+ # assertion/expectation library such as wrong or the stdlib/minitest
24
+ # assertions if you prefer.
25
+ config.expect_with :rspec do |expectations|
26
+ expectations.syntax = :should
27
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
28
+ end
29
+
30
+ # rspec-mocks config goes here. You can use an alternate test double
31
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
32
+ config.mock_with :rspec do |mocks|
33
+ # Prevents you from mocking or stubbing a method that does not exist on
34
+ # a real object. This is generally recommended, and will default to
35
+ # `true` in RSpec 4.
36
+ mocks.verify_partial_doubles = true
37
+ end
38
+
39
+ # These two settings work together to allow you to limit a spec run
40
+ # to individual examples or groups you care about by tagging them with
41
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
42
+ # get run.
43
+ config.filter_run :focus
44
+ config.run_all_when_everything_filtered = true
45
+
46
+ # This setting enables warnings. It's recommended, but in some cases may
47
+ # be too noisy due to issues in dependencies.
48
+ # config.warnings = true
49
+
50
+ # Many RSpec users commonly either run the entire suite or an individual
51
+ # file, and it's useful to allow more verbose output when running an
52
+ # individual spec file.
53
+ if config.files_to_run.one?
54
+ # Use the documentation formatter for detailed output,
55
+ # unless a formatter has already been configured
56
+ # (e.g. via a command-line flag).
57
+ config.default_formatter = 'doc'
58
+ end
59
+
60
+ # Print the 10 slowest examples and example groups at the
61
+ # end of the spec run, to help surface which specs are running
62
+ # particularly slow.
63
+ # config.profile_examples = 10
64
+
65
+ # Run specs in random order to surface order dependencies. If you find an
66
+ # order dependency and want to debug it, you can fix the order by providing
67
+ # the seed, which is printed after each run.
68
+ # --seed 1234
69
+ #config.order = :random
70
+
71
+ # Seed global randomization in this process using the `--seed` CLI option.
72
+ # Setting this allows you to use `--seed` to deterministically reproduce
73
+ # test failures related to randomization by passing the same `--seed` value
74
+ # as the one that triggered the failure.
75
+ #Kernel.srand config.seed
76
+ end
@@ -0,0 +1,159 @@
1
+ require 'pacer-scale/version'
2
+ require 'pacer'
3
+ require 'lock_jar'
4
+ LockJar.lock File.join(File.dirname(__FILE__), '../../Jarfile'), lockfile: 'Jarfile.pacer-mcfly.lock'
5
+ LockJar.load 'Jarfile.pacer-mcfly.lock'
6
+ require 'xn_graph_scale.jar'
7
+
8
+ module PacerScale
9
+ import java.math.BigDecimal
10
+ import Java::clojure.java.api.Clojure
11
+ import Java::xn.graph.scale.ScaleRangePipe
12
+
13
+ class << self
14
+ def generate_scale(graph, min, max, step)
15
+ Clojure.var('clojure.core', 'require').invoke(['xn.graph.scale.core'])
16
+ gs = Clojure.var('xn.graph.scale.core', 'generate-scale')
17
+ v = gs.invoke(graph.blueprints_graph, min.to_i, max.to_i, BigDecimal.new(step.to_s))
18
+ graph.vertex(v.getId, Value) if v
19
+ end
20
+ end
21
+
22
+ module Root
23
+ module Vertex
24
+ def generate_scale(label, min, max, step)
25
+ v = PacerScale.generate_scale(graph, min, max, step)
26
+ add_edges_to(label, v)
27
+ v[:root_edge] = label
28
+ self
29
+ end
30
+
31
+ def find(label, val)
32
+ out(label, Value).first.find val
33
+ end
34
+
35
+ def find_range(label, val, tolerance)
36
+ out(label, Value).first.find_range val, tolerance
37
+ end
38
+ end
39
+ end
40
+
41
+ module Value
42
+ module Vertex
43
+ def value
44
+ v = self[:scale_value]
45
+ v.to_f if v
46
+ end
47
+
48
+ def min
49
+ v = self[:scale_min]
50
+ v.to_f if v
51
+ end
52
+
53
+ def max
54
+ v = self[:scale_max]
55
+ v.to_f if v
56
+ end
57
+
58
+ def step
59
+ v = self[:scale_step]
60
+ v.to_f if v
61
+ end
62
+
63
+ def root
64
+ v = find(min)
65
+ v.in(v[:root_edge], Root) if v
66
+ end
67
+
68
+ def next
69
+ out(:next_1, Value)
70
+ end
71
+
72
+ def prev
73
+ self.in(:next_1, Value)
74
+ end
75
+
76
+ def find(val)
77
+ # calculate offset from current position...
78
+ offset(val - value, 0).first
79
+ end
80
+
81
+ def offset(offset_by, tolerance)
82
+ _as_scale.offset(offset_by, tolerance)
83
+ end
84
+
85
+ def below(offset_by = 0)
86
+ _as_scale.below_traversal(offset_by)
87
+ end
88
+
89
+ def above(offset_by = 0)
90
+ _as_scale.above_traversal(offset_by)
91
+ end
92
+
93
+ def find_range(val, tolerance)
94
+ # calculate offset_by from current position...
95
+ offset(val - value, tolerance)
96
+ end
97
+
98
+ protected
99
+
100
+ def _as_scale
101
+ chain_route(filter: PacerScale::RangeTraversal,
102
+ min: min, max: max, step: step)
103
+ end
104
+ end
105
+
106
+ module Route
107
+ def as_scale(min, max, step)
108
+ chain_route(filter: PacerScale::RangeTraversal,
109
+ min: min, max: max, step: step)
110
+ end
111
+ end
112
+ end
113
+
114
+ module RangeTraversal
115
+ attr_accessor :min, :max, :step, :offset_by, :above_tolerance, :below_tolerance
116
+
117
+ def offset(offset_by, t_below, t_above = nil)
118
+ t_above ||= t_below
119
+ @offset_by = offset_by
120
+ @below_tolerance = t_below
121
+ @above_tolerance = t_above
122
+ v(extensions)
123
+ end
124
+
125
+ def above(offset_by = 0)
126
+ @offset_by = offset_by
127
+ @below_tolerance = 0
128
+ @above_tolerance = nil
129
+ v(extensions)
130
+ end
131
+
132
+ def below(offset_by = 0)
133
+ @offset_by = offset_by
134
+ @below_tolerance = nil
135
+ @above_tolerance = 0
136
+ v(extensions)
137
+ end
138
+
139
+ protected
140
+
141
+ def bigdec(n)
142
+ BigDecimal.new(n.to_s) if n
143
+ end
144
+
145
+ def inspect_string
146
+ if above_tolerance == below_tolerance
147
+ "offset(#{ offset_by }, #{above_tolerance})"
148
+ else
149
+ "offset(#{ offset_by }, #{below_tolerance.inspect}, #{above_tolerance.inspect})"
150
+ end
151
+ end
152
+
153
+ def attach_pipe(end_pipe)
154
+ pipe = ScaleRangePipe.new(min, max, bigdec(step), bigdec(offset_by || 0), bigdec(below_tolerance), bigdec(above_tolerance))
155
+ pipe.set_starts end_pipe if end_pipe
156
+ pipe
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,3 @@
1
+ module PacerScale
2
+ VERSION = "0.1.0"
3
+ end
Binary file
@@ -0,0 +1,194 @@
1
+ (ns xn.graph.scale.core-test
2
+ (:use xn.graph.scale.core
3
+ criterium.core)
4
+ (import java.math.BigDecimal
5
+ (com.tinkerpop.blueprints Graph Direction Edge Element Vertex)
6
+ com.tinkerpop.blueprints.impls.tg.TinkerGraph
7
+ xn.graph.scale.ScaleRangePipe)
8
+ (:require [clojure.test :refer [deftest is]]
9
+ [clojure.test.check.clojure-test :refer [defspec]]
10
+ [clojure.test.check :as tc]
11
+ [clojure.test.check.generators :as gen]
12
+ [clojure.test.check.properties :as prop]))
13
+
14
+ (defspec
15
+ steps-add-up-to-traversal-distance
16
+ 100 ;; the number of iterations for test.check to test
17
+ (prop/for-all [from gen/pos-int
18
+ to gen/pos-int]
19
+ (= (- to from)
20
+ (apply + (traversal-steps from to)))))
21
+
22
+ (defn big-traversal [from to multiplier]
23
+ (let [from (* from (inc multiplier) (inc multiplier))
24
+ to (* to (inc multiplier) (inc multiplier))
25
+ steps (traversal-steps from to)]
26
+ (= (- to from)
27
+ (apply + steps))))
28
+
29
+ (defspec
30
+ bigger-steps-add-up-to-traversal-distance
31
+ 100
32
+ (prop/for-all [from gen/pos-int
33
+ to gen/pos-int
34
+ multiplier gen/pos-int]
35
+ (big-traversal from to multiplier)))
36
+
37
+ (def gen-decimal
38
+ (->> gen/ratio
39
+ (gen/fmap #(try
40
+ (BigDecimal. (str (float (if (neg? %) (* -1 %) %))))
41
+ (catch ArithmeticException e nil)))
42
+ (gen/such-that some?)))
43
+
44
+ (defn gen-nonzero [gen]
45
+ (gen/such-that #(not (zero? %)) gen))
46
+
47
+ (defn predicted-edges [max-idx]
48
+ (reduce
49
+ (fn [m d]
50
+ (if-let [data (->> (range 0 max-idx)
51
+ (filter #(= 0 (mod % d)))
52
+ (partition 2 1)
53
+ seq)]
54
+ (assoc m d data)
55
+ m))
56
+ {}
57
+ distances))
58
+
59
+ (defspec
60
+ generate-various-scales
61
+ 100
62
+ (prop/for-all
63
+ [[from to step]
64
+ (->> (gen/tuple gen/int gen/int (gen-nonzero gen-decimal) gen/int)
65
+ (gen/fmap (fn [[from to step mult]]
66
+ [(* from mult) (* to mult) step]))
67
+ (gen/such-that (fn [[from to]] (not= from to)))
68
+ (gen/fmap
69
+ (fn [[from to step]]
70
+ (if (< from to)
71
+ [from to step]
72
+ [to from step])))
73
+ (gen/fmap
74
+ (fn [[from to step]]
75
+ (loop [from from to to step step]
76
+ (if (<= (- to from) step)
77
+ (recur from to (/ step 2))
78
+ [from to step])))))]
79
+ (let [vertices (atom (transient []))
80
+ edges (atom (transient {}))]
81
+ (with-redefs [scale-vertex
82
+ (fn [g scale i]
83
+ (swap! vertices conj! i)
84
+ i)
85
+ scale-edge
86
+ (fn [g from to dist]
87
+ (swap! edges assoc! dist (conj (@edges dist []) [from to])))]
88
+ (generate-scale nil from to step)
89
+ (let [max-idx (inc (long (Math/round (/ (double (- to from)) (double step)))))]
90
+ ;(prn [from to step] max-idx)
91
+ (is (= (range 0 max-idx)
92
+ (persistent! @vertices)))
93
+ (is (= (predicted-edges max-idx)
94
+ (persistent! @edges))))))))
95
+
96
+
97
+
98
+ (let [g (TinkerGraph.)
99
+ v0 (generate-scale g -500 500 0.1M)
100
+ label (into-array String ["next_1"])
101
+ actual (loop [actual {} v v0]
102
+ (if v
103
+ (recur (assoc actual (value v) v)
104
+ (first (.getVertices ^Vertex v Direction/OUT label)))
105
+ actual))]
106
+ (defspec
107
+ navagate-a-real-scale
108
+ 1000
109
+ (prop/for-all
110
+ [[start offset tolerance] (->> (gen/tuple gen/int gen/int gen/ratio)
111
+ (gen/fmap
112
+ (fn [[s o t]]
113
+ (if (neg? t) [s o (- t)] [s o t])))
114
+ (gen/such-that
115
+ (fn [[s o t]]
116
+ (and (<= -500 s 500)
117
+ (<= -500 (+ s o (- t)) (+ s o t) 500)))))]
118
+ (let [start (BigDecimal. (str start))
119
+ s (actual start)
120
+ expected (actual (+ start offset))
121
+ tolerance (BigDecimal. (str (double tolerance)))
122
+ f (scale-range -500 500 0.1M (BigDecimal. (str offset)) tolerance tolerance)
123
+ r (f s)]
124
+ (is (some #{expected} r)))))
125
+
126
+ (deftest test-range-end
127
+ (let [f (scale-range -500 500 0.1M 1000M 0M 0M)]
128
+ (is (not (empty? (f v0))))
129
+ (is (= [500M] (map value (f v0))))))
130
+
131
+ (deftest test-range-pipe
132
+ (let [pipe (ScaleRangePipe. -500 500 0.1M 550M 1M 5M)
133
+ a (java.util.ArrayList.)]
134
+ (.add a v0)
135
+ (.setStarts pipe a)
136
+ (is (= (into [] (map actual) (range 49M 55.01M 0.1M))
137
+ (into [] (seq pipe)))))))
138
+
139
+
140
+ (defspec
141
+ no-falling-off-the-head
142
+ 1000
143
+ (prop/for-all
144
+ [[low high] (->> (gen/tuple gen/pos-int gen/pos-int)
145
+ (gen/such-that (fn [[l h]] (not= l h)))
146
+ (gen/fmap (fn [[l h]] (if (< l h) [l h] [h l]))))]
147
+ (let [g (TinkerGraph.)
148
+ v0 (generate-scale g low high 1M)
149
+ label (into-array String ["next_1"])
150
+ ^Vertex vn (loop [vn v0 ^Vertex v v0]
151
+ (if v
152
+ (recur v
153
+ (first (.getVertices v Direction/OUT label)))
154
+ vn))]
155
+ (every? (fn [n]
156
+ (let [f (scale-range low high 1M (- n) 0M 0M)
157
+ data (doall (f vn))
158
+ expected (- high n)]
159
+ (is (= [expected] (map value data)))))
160
+ (range 0M (BigDecimal. (str (- high low))))))))
161
+
162
+
163
+ (defspec
164
+ no-falling-off-the-end
165
+ 100
166
+ (prop/for-all
167
+ [[low high] (->> (gen/tuple gen/int gen/int)
168
+ (gen/such-that (fn [[l h]] (not= l h)))
169
+ (gen/fmap (fn [[l h]] (if (< l h) [l h] [h l]))))]
170
+ (let [g (TinkerGraph.)
171
+ v0 (generate-scale g low high 1M)]
172
+ (every? (fn [n]
173
+ (let [f (scale-range low high 1M n 0M 0M)]
174
+ (is (= [(+ low n)] (map value (f v0))))))
175
+ (range 0M (BigDecimal. (str (- high low))))))))
176
+
177
+
178
+
179
+
180
+ (deftest inline-tests
181
+ (test #'tests))
182
+
183
+ (comment
184
+ (drop 9900 (gen/sample
185
+ (gen/fmap (fn [[a b c]] [(* a c) (* b c)])
186
+ (gen/tuple gen/pos-int gen/pos-int gen/pos-int))
187
+ 10000))
188
+
189
+ (gen/sample (gen/such-that #(not (zero? %)) gen-decimal) 100)
190
+ (gen/sample (gen/such-that #(apply not= %) (gen/tuple gen/int gen/int)) 1000)
191
+
192
+ (quick-bench (remove-oversized-steps {:min 0 :max 100 :step 1M} 0 [100 -1 -1 -1]))
193
+ (bench (remove-oversized-steps {:min 0 :max 99 :step 1M} 0 [100 -1 -1 -1]))
194
+ (quick-bench (traversal-steps 3608 943)))
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pacer-scale
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: java
6
+ authors:
7
+ - Darrick Wiebe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lock_jar
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.2
20
+ requirement: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: 0.10.2
25
+ prerelease: false
26
+ type: :runtime
27
+ - !ruby/object:Gem::Dependency
28
+ name: pacer
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ prerelease: false
40
+ type: :runtime
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ prerelease: false
54
+ type: :development
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-its
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ prerelease: false
68
+ type: :development
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ prerelease: false
82
+ type: :development
83
+ - !ruby/object:Gem::Dependency
84
+ name: builder
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirement: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ prerelease: false
96
+ type: :development
97
+ - !ruby/object:Gem::Dependency
98
+ name: nokogiri
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - '>='
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ prerelease: false
110
+ type: :development
111
+ - !ruby/object:Gem::Dependency
112
+ name: xn_gem_release_tasks
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: 0.1.21
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - '>='
121
+ - !ruby/object:Gem::Version
122
+ version: 0.1.21
123
+ prerelease: false
124
+ type: :development
125
+ description: Generate and produce ranges in scale data structures in the graph
126
+ email:
127
+ - dw@xnlogic.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - Jarfile
133
+ - spec/pacer-scale_spec.rb
134
+ - spec/spec_helper.rb
135
+ - src/ruby/pacer-scale.rb
136
+ - src/ruby/pacer-scale/version.rb
137
+ - src/ruby/xn_graph_scale.jar
138
+ - test/xn/graph/scale/core_test.clj
139
+ homepage: http://xnlogic.com
140
+ licenses: []
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - src/ruby
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project: pacer-scale
158
+ rubygems_version: 2.4.5
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: Scale plugin for Pacer
162
+ test_files:
163
+ - spec/pacer-scale_spec.rb
164
+ - spec/spec_helper.rb
165
+ - test/xn/graph/scale/core_test.clj