navigable-router 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fcd2c783613974e0cfc498e7fed135d9c24faaac631c5492f1d80d7b800cfb4
4
- data.tar.gz: 7e5959b84ec2c0508dab57e67c2a869cb92fb85230b2e7933a9ec698f849a1fe
3
+ metadata.gz: c748cefb4d44f7c08276fc8184e1c7409cba3527805e10723bcd6717e61f5673
4
+ data.tar.gz: 7517903e1cb426baaf2abb0998e58a65c68ac7b039b85db3c9a9a74b5fea5d68
5
5
  SHA512:
6
- metadata.gz: ba294b063321dcb00cdf45d6130ba16debbd827381c74b7d51c48b4227e9a59526ae60642dcbdb6cf410f4983a801fbe1627ed82ad8b040bf5e28845e9306c05
7
- data.tar.gz: e2b2b309c9b212c68bfb8b5544c9b837d8487b8ef94f00627ac7dd1d78e3034cb49fabaefd7dc6847017400949e103d380a643454eb48ffa9734f44a5fb71518
6
+ metadata.gz: 341079c0f664ddd3bfd0bc49784387e682b7c7e3885cb2f9669665624fb0f6e64ba544109e9fcc7d5cf9af33c575937ffd21f74ee15cfcf15b66810720e25236
7
+ data.tar.gz: d740816ccda07355f5d393bbb4179162f4f57ce3735af576026f6bb232872f99dad92c0f400441eadd8c3774dcf3d053f9b9b8e6136b2822091851f33e5a4ccc
@@ -4,3 +4,11 @@ cache: bundler
4
4
  rvm:
5
5
  - 2.7.1
6
6
  before_install: gem install bundler -v 2.1.4
7
+ before_script:
8
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
9
+ - chmod +x ./cc-test-reporter
10
+ - ./cc-test-reporter before-build
11
+ script:
12
+ - bundle exec rspec
13
+ after_script:
14
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/README.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # Navigable::Router
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/navigable-router.svg)](https://badge.fury.io/rb/navigable-router) [![Build Status](https://travis-ci.org/first-try-software/navigable-router.svg?branch=main)](https://travis-ci.org/first-try-software/navigable-router) [![Maintainability](https://api.codeclimate.com/v1/badges/514b9791fb670b7a3abb/maintainability)](https://codeclimate.com/github/first-try-software/navigable-router/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/514b9791fb670b7a3abb/test_coverage)](https://codeclimate.com/github/first-try-software/navigable-router/test_coverage)
4
+
5
+ Navigable is a family of gems that together provide all the tools you need to build fast, testable, and reliable JSON and/or GraphQL based APIs with isolated, composable business logic. The gems include:
6
+
7
+ <table style="margin: 20px 0">
8
+ <tr height="140">
9
+ <td width="130"><img alt="Clipper Ship" src="https://raw.githubusercontent.com/first-try-software/navigable/main/assets/clipper.png"></td>
10
+ <td>
11
+
12
+ **[Navigable][navigable]**<br>
13
+ A stand-alone tool for isolating business logic from external interfaces and cross-cutting concerns. Navigable composes self-configured command and observer objects to allow you to extend your business logic without modifying it. Navigable is compatible with any Ruby-based application development framework, including Rails, Hanami, and Sinatra.
14
+
15
+ </td>
16
+ </tr>
17
+ <tr height="140">
18
+ <td width="130"><img alt="Compass" src="https://raw.githubusercontent.com/first-try-software/navigable/main/assets/sextant.png"></td>
19
+ <td>
20
+
21
+ **[Navigable Router][router]** *(coming soon)*<br>
22
+ A simple, highly-performant, Rack-based router.
23
+
24
+ </td>
25
+ </tr>
26
+ <tr height="140">
27
+ <td width="130"><img alt="Compass" src="https://raw.githubusercontent.com/first-try-software/navigable/main/assets/compass.png"></td>
28
+ <td>
29
+
30
+ **[Navigable Server][server]** *(coming soon)*<br>
31
+ A Rack-based server for building Ruby and Navigable web applications.
32
+
33
+ </td>
34
+ </tr>
35
+ <tr height="140">
36
+ <td width="130"><img alt="Telescope" src="https://raw.githubusercontent.com/first-try-software/navigable/main/assets/telescope.png"></td>
37
+ <td>
38
+
39
+ **Navigable API** *(coming soon)*<br>
40
+ An extension of Navigable Server for building restful JSON APIs.
41
+
42
+ </td>
43
+ </tr>
44
+ <tr height="140">
45
+ <td width="130"><img alt="Map" src="https://raw.githubusercontent.com/first-try-software/navigable/main/assets/map.png"></td>
46
+ <td>
47
+
48
+ **Navigable GraphQL** *(coming soon)*<br>
49
+ An extension of Navigable Server for building GraphQL APIs.
50
+
51
+ </td>
52
+ </tr>
53
+ </table>
54
+
3
55
  ## Installation
4
56
 
5
57
  Add this line to your application's Gemfile:
@@ -18,7 +70,25 @@ Or install it yourself as:
18
70
 
19
71
  ## Usage
20
72
 
21
- TODO: Write usage instructions here
73
+ To use `Navigable::Router` simply instantiate a router and add your routes:
74
+
75
+ ```ruby
76
+ router = Navigable::Router.new
77
+ router.get('/ahoy', to: -> (env) { [200, { 'Content-Type' => 'text/html' }, [ 'Ahoy!' ]] })
78
+ ```
79
+ The destination of the route needs to respond to `#call`, like the lambda above, or these classes:
80
+
81
+ ```ruby
82
+ router.get('/swabbies', to: ShowSwabbies)
83
+ router.get('/swabbies/:id', to: ShowSwabbie)
84
+ router.post('/swabbies', to: CreateSwabbie)
85
+ router.put('/swabbies/:id', to: UpdateSwabbie)
86
+ router.delete('/swabbies/:id', to: DeleteSwabbie)
87
+ ```
88
+ To run the app, add this to your config.ru:
89
+ ```ruby
90
+ run router
91
+ ```
22
92
 
23
93
  ## Development
24
94
 
@@ -28,7 +98,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
28
98
 
29
99
  ## Contributing
30
100
 
31
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/navigable-router. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/navigable-router/blob/master/CODE_OF_CONDUCT.md).
101
+ Bug reports and pull requests are welcome on GitHub at https://github.com/first-try-softare/navigable-router. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/first-try-softare/navigable-router/blob/master/CODE_OF_CONDUCT.md).
32
102
 
33
103
 
34
104
  ## License
@@ -37,4 +107,8 @@ The gem is available as open source under the terms of the [MIT License](https:/
37
107
 
38
108
  ## Code of Conduct
39
109
 
40
- Everyone interacting in the Navigable::Router project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/navigable-router/blob/master/CODE_OF_CONDUCT.md).
110
+ Everyone interacting in the Navigable::Router project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/first-try-software/navigable-router/blob/master/CODE_OF_CONDUCT.md).
111
+
112
+ [navigable]: https://github.com/first-try-software/navigable
113
+ [router]: https://github.com/first-try-software/navigable-router
114
+ [server]: https://github.com/first-try-software/navigable-server
@@ -4,6 +4,7 @@ require 'mustermann'
4
4
 
5
5
  require 'navigable/router/version'
6
6
  require 'navigable/router/trie'
7
+ require 'navigable/router/printer'
7
8
 
8
9
  module Navigable
9
10
  class Router
@@ -50,6 +51,10 @@ module Navigable
50
51
  endpoint ? endpoint.call(env) : NOT_FOUND_RESPONSE
51
52
  end
52
53
 
54
+ def print(stdout = STDOUT)
55
+ Printer.new(@static, @dynamic, stdout).print
56
+ end
57
+
53
58
  private
54
59
 
55
60
  def register_route(verb, path, to)
@@ -85,4 +90,4 @@ module Navigable
85
90
  @static[verb][path] = to
86
91
  end
87
92
  end
88
- end
93
+ end
@@ -19,13 +19,18 @@ module Navigable
19
19
  end
20
20
 
21
21
  def find(segment)
22
- find_node(segment) { |params| yield(symbolize_keys(params)) if params && block_given? } unless empty?
22
+ find_node(segment) { |params| yield(symbolize_keys(params)) if params && block_given? }
23
23
  end
24
24
 
25
25
  def attach(endpoint)
26
26
  @endpoint = endpoint
27
27
  end
28
28
 
29
+ def print(verb, routes, prefix = '')
30
+ print_segments(@static, routes, verb, prefix)
31
+ print_segments(@dynamic, routes, verb, prefix)
32
+ end
33
+
29
34
  private
30
35
 
31
36
  def add_static(segment)
@@ -39,6 +44,8 @@ module Navigable
39
44
  end
40
45
 
41
46
  def find_node(segment, &block)
47
+ return if empty?
48
+
42
49
  find_static(segment, &block) || find_dynamic(segment, &block)
43
50
  end
44
51
 
@@ -68,6 +75,13 @@ module Navigable
68
75
  def symbolize_keys(hash)
69
76
  hash.each_with_object({}) { |(key, value), obj| obj[key.to_sym] = value }
70
77
  end
78
+
79
+ def print_segments(segments, routes, verb, prefix)
80
+ segments&.each do |segment, node|
81
+ routes << { verb: verb, path: "#{prefix}/#{segment}", endpoint: node.endpoint } if node.endpoint
82
+ node.print(verb, routes, "#{prefix}/#{segment}")
83
+ end
84
+ end
71
85
  end
72
86
  end
73
87
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Navigable
4
+ class Router
5
+ class Printer
6
+ VERBS = %w(GET HEAD POST PUT PATCH DELETE).freeze
7
+
8
+ attr_reader :static, :dynamic, :memo, :stdout
9
+
10
+ def initialize(static, dynamic, stdout = STDOUT)
11
+ @static, @dynamic = static, dynamic
12
+ @stdout = stdout
13
+ @memo = []
14
+ end
15
+
16
+ def print
17
+ gather_static_routes
18
+ gather_dynamic_routes
19
+ print_routes
20
+ end
21
+
22
+ private
23
+
24
+ def gather_static_routes
25
+ static.each do |verb, routes|
26
+ routes.each do |path, endpoint|
27
+ memo << { verb: verb, path: path, endpoint: endpoint }
28
+ end
29
+ end
30
+ end
31
+
32
+ def gather_dynamic_routes
33
+ dynamic.each do |verb, trie|
34
+ trie.print(verb, memo)
35
+ end
36
+ end
37
+
38
+ def print_routes
39
+ sorted_routes.each { |route| print_route(route) }
40
+ end
41
+
42
+ def sorted_routes
43
+ memo.sort_by { |route| "#{route[:path]}-#{VERBS.find_index(route[:verb])}" }
44
+ end
45
+
46
+ def print_route(route)
47
+ stdout.puts "#{pad(route[:verb], 8)} #{pad(route[:path], -50)} => #{route[:endpoint]}"
48
+ end
49
+
50
+ def pad(str, length)
51
+ "%#{length}s" % str
52
+ end
53
+ end
54
+ end
55
+ end
@@ -26,6 +26,10 @@ module Navigable
26
26
  node&.endpoint
27
27
  end
28
28
 
29
+ def print(verb, routes)
30
+ @root.print(verb, routes)
31
+ end
32
+
29
33
  private
30
34
 
31
35
  def traverse(path)
@@ -1,5 +1,5 @@
1
1
  module Navigable
2
2
  class Router
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "rake", "~> 12.0"
32
32
  spec.add_development_dependency "rspec", "~> 3.0"
33
33
  spec.add_development_dependency "rspec_junit_formatter", "~>0.4"
34
- spec.add_development_dependency "simplecov", "~>0.17"
34
+ spec.add_development_dependency "simplecov", "~>0.17.0"
35
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: navigable-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alan Ridlehoover
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-09-21 00:00:00.000000000 Z
12
+ date: 2020-09-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mustermann
@@ -115,14 +115,14 @@ dependencies:
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: '0.17'
118
+ version: 0.17.0
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: '0.17'
125
+ version: 0.17.0
126
126
  description: A simple, highly-performant, Rack-based router.
127
127
  email:
128
128
  - navigable@firsttry.software
@@ -142,6 +142,7 @@ files:
142
142
  - bin/setup
143
143
  - lib/navigable/router.rb
144
144
  - lib/navigable/router/node.rb
145
+ - lib/navigable/router/printer.rb
145
146
  - lib/navigable/router/trie.rb
146
147
  - lib/navigable/router/version.rb
147
148
  - navigable-router.gemspec