hub_kernel 0.9.0 → 0.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c55c177c5ca371059cf35185392a5b283a314254dff6b18aa2d13f7c12793cd
4
- data.tar.gz: 23afef8f196447cecf97c1b2e0355aba897388784e2c1ddb80d6ff7ff9da7f98
3
+ metadata.gz: 269ad669e7c014af9175190d416dbf7be82bfb8d797eb3a25107bf87b99b1344
4
+ data.tar.gz: 808639ddaca46f8d8cbe9f187a7d59ae9d50b704f773bf4f255bae731d4339a7
5
5
  SHA512:
6
- metadata.gz: 61caa0ec7d31d6fbd86dc005dae507895eb2a7e4a1f1c09b3be2976edbc8ff69b5f14108a007dffe38b501b4d773250544ed625457d87e8ed7cbdf7f811796ff
7
- data.tar.gz: 532c56d1800f02ab79faab68553fc75edd7f20bdcbc8677d2a4e7416dde7ec063ff79c94825db9bf99f10bd380b5874d52657e6beef5a03b8ef08532b6c71a93
6
+ metadata.gz: 3c94024970cd0ae83bf695824439a959b6b03061eb39f92268f483ca769fbf323d4210710f805f052028590e65b87a84b43b8801cac1a9b927a9402205f1fd55
7
+ data.tar.gz: 307661997442f598ee6d2e931540336986a567794113298d496864f86d3ac19e2788ee091e75b8bc9434bd1c61bd3aa1df095b71af29d2479b7898869dfd416b
data/README.md CHANGED
@@ -134,6 +134,36 @@ end
134
134
  The test fails and names each problem. A method that takes `**` values accepts any
135
135
  values it is listed with, as long as it is listed with each value it requires.
136
136
 
137
+ ### The crossing check
138
+ A host's test can check that no hub's code names a class another hub owns. The host
139
+ passes a map of which classes each hub owns, and the test fails listing each file and
140
+ the class it names:
141
+
142
+ ```ruby
143
+ require "hub_kernel/conformance/crossings"
144
+
145
+ class HubCrossingsTest < ActiveSupport::TestCase
146
+ include HubKernel::Conformance::Crossings
147
+
148
+ crossings files: "app/{models,controllers,jobs,views}/shop/**/*.{rb,erb}", except: [ "app/models/shop/hubs.rb" ] do
149
+ HubKernel::Crossings.new(
150
+ owners: { supplies: %w[Shop::Purchase Shop::PurchasesController], finance: %w[Shop::Expense], shop: %w[Shop::Home] },
151
+ shared: %w[Shop::BaseController],
152
+ host_layer: :shop,
153
+ interfaces: { supplies: "Shop::Hubs::Supplies", finance: "Shop::Hubs::Finance" }
154
+ )
155
+ end
156
+ end
157
+ ```
158
+
159
+ - A constant inside another hub's class counts as naming that class.
160
+ - A name no hub owns, such as a namespace, is not a crossing, and neither is a class on
161
+ the `shared` list.
162
+ - A view belongs to the hub that owns its controller, then to the hub that owns the
163
+ record its folder is named after, and otherwise to the `host_layer`.
164
+ - The host's layer may name any hub's interface module, and a hub naming another hub's
165
+ interface module is a crossing.
166
+
137
167
  ## Installation
138
168
  Add this line to your application's Gemfile:
139
169
 
@@ -0,0 +1,28 @@
1
+ require "active_support/concern"
2
+ require "hub_kernel/crossings"
3
+
4
+ module HubKernel
5
+ module Conformance
6
+ module Crossings
7
+ extend ActiveSupport::Concern
8
+
9
+ class_methods do
10
+ def crossings(root: nil, files: "app/**/*.{rb,erb}", except: [], &block)
11
+ define_method(:the_crossings, &block)
12
+ define_method(:crossing_root) { root || Rails.root }
13
+ define_method(:crossing_files) { files }
14
+ define_method(:crossing_exceptions) { except }
15
+ end
16
+ end
17
+
18
+ included do
19
+ test "no file names a class another hub owns" do
20
+ found = (Dir.glob(crossing_files, base: crossing_root) - crossing_exceptions).sort.flat_map do |path|
21
+ the_crossings.in(path, File.read(File.join(crossing_root, path))).map { |name| "#{path} names #{name}" }
22
+ end
23
+ flunk found.join("\n") if found.any?
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,40 @@
1
+ require "active_support/core_ext/string/inflections"
2
+
3
+ module HubKernel
4
+ class Crossings
5
+ def initialize(owners:, shared: [], host_layer: nil, interfaces: {})
6
+ @owners = owners
7
+ @shared = shared
8
+ @host_layer = host_layer
9
+ @interfaces = interfaces
10
+ end
11
+
12
+ def in(path, source)
13
+ hub = owner_of_file(path)
14
+ source.scan(/[A-Z]\w*(?:::[A-Z]\w*)*/).filter_map { |name| owned_class_in(name) }.uniq.select { |name| crossing?(name, hub) }
15
+ end
16
+
17
+ private
18
+
19
+ def crossing?(name, hub)
20
+ return false if @shared.include?(name) || owner_of(name) == hub
21
+
22
+ !(hub == @host_layer && @interfaces.value?(name))
23
+ end
24
+
25
+ def owned_class_in(name)
26
+ parts = name.split("::")
27
+ parts.size.downto(1).map { |size| parts.first(size).join("::") }.find { |candidate| owner_of(candidate) }
28
+ end
29
+
30
+ def owner_of(class_name) = @interfaces.key(class_name) || @owners.find { |_hub, classes| classes.include?(class_name) }&.first
31
+
32
+ def owner_of_file(path)
33
+ return owner_of_view_folder(File.dirname(path.delete_prefix("app/views/")).camelize) if path.start_with?("app/views/")
34
+
35
+ owner_of(path.sub(%r{\Aapp/[^/]+/}, "").delete_suffix(".rb").camelize)
36
+ end
37
+
38
+ def owner_of_view_folder(folder) = owner_of("#{folder}Controller") || owner_of(folder) || @host_layer
39
+ end
40
+ end
@@ -1,3 +1,3 @@
1
1
  module HubKernel
2
- VERSION = "0.9.0"
2
+ VERSION = "0.10.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hub_kernel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tylercschneider
@@ -42,10 +42,12 @@ files:
42
42
  - lib/hub_kernel/answer.rb
43
43
  - lib/hub_kernel/authz.rb
44
44
  - lib/hub_kernel/conformance/action.rb
45
+ - lib/hub_kernel/conformance/crossings.rb
45
46
  - lib/hub_kernel/conformance/exposed.rb
46
47
  - lib/hub_kernel/conformance/hub.rb
47
48
  - lib/hub_kernel/conformance/partial.rb
48
49
  - lib/hub_kernel/context.rb
50
+ - lib/hub_kernel/crossings.rb
49
51
  - lib/hub_kernel/engine.rb
50
52
  - lib/hub_kernel/exposes.rb
51
53
  - lib/hub_kernel/follow_up.rb