kangaru 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +2 -0
  4. data/Steepfile +2 -0
  5. data/kangaru.gemspec +1 -1
  6. data/lib/kangaru/application.rb +5 -1
  7. data/lib/kangaru/concerns/configurable.rb +1 -1
  8. data/lib/kangaru/controller.rb +4 -4
  9. data/lib/kangaru/database.rb +1 -1
  10. data/lib/kangaru/initialisers/rspec/kangaru_helper.rb +18 -0
  11. data/lib/kangaru/initialisers/rspec/request_helper.rb +70 -0
  12. data/lib/kangaru/initialisers/rspec.rb +7 -1
  13. data/lib/kangaru/injected_methods.rb +5 -5
  14. data/lib/kangaru/router.rb +5 -4
  15. data/lib/kangaru/version.rb +1 -1
  16. data/lib/kangaru.rb +3 -3
  17. data/sig/class.rbs +3 -0
  18. data/sig/kangaru/application.rbs +34 -0
  19. data/sig/kangaru/argument_parser.rbs +17 -0
  20. data/sig/kangaru/components/component.rbs +9 -0
  21. data/sig/kangaru/concerns/attributes_concern.rbs +25 -0
  22. data/sig/kangaru/concerns/concern.rbs +15 -0
  23. data/sig/kangaru/concerns/configurable.rbs +15 -0
  24. data/sig/kangaru/concerns/validatable.rbs +28 -0
  25. data/sig/kangaru/config.rbs +27 -0
  26. data/sig/kangaru/configurators/application_configurator.rbs +7 -0
  27. data/sig/kangaru/configurators/configurator.rbs +14 -0
  28. data/sig/kangaru/configurators/database_configurator.rbs +9 -0
  29. data/sig/kangaru/configurators/external_configurator.rbs +6 -0
  30. data/sig/kangaru/configurators/open_configurator.rbs +11 -0
  31. data/sig/kangaru/configurators/request_configurator.rbs +7 -0
  32. data/sig/kangaru/configurators.rbs +7 -0
  33. data/sig/kangaru/controller.rbs +23 -0
  34. data/sig/kangaru/database.rbs +31 -0
  35. data/sig/kangaru/inflectors/class_inflector.rbs +6 -0
  36. data/sig/kangaru/inflectors/constant_inflector.rbs +7 -0
  37. data/sig/kangaru/inflectors/constantiser.rbs +9 -0
  38. data/sig/kangaru/inflectors/human_inflector.rbs +6 -0
  39. data/sig/kangaru/inflectors/inflector.rbs +47 -0
  40. data/sig/kangaru/inflectors/inflector_macros.rbs +23 -0
  41. data/sig/kangaru/inflectors/path_inflector.rbs +7 -0
  42. data/sig/kangaru/inflectors/screaming_snakecase_inflector.rbs +6 -0
  43. data/sig/kangaru/inflectors/snakecase_inflector.rbs +6 -0
  44. data/sig/kangaru/inflectors/tokeniser.rbs +14 -0
  45. data/sig/kangaru/initialiser.rbs +9 -0
  46. data/sig/kangaru/initialisers/rspec.rbs +6 -0
  47. data/sig/kangaru/injected_methods.rbs +17 -0
  48. data/sig/kangaru/model.rbs +16 -0
  49. data/sig/kangaru/patches/constantise.rbs +9 -0
  50. data/sig/kangaru/patches/inflections.rbs +15 -0
  51. data/sig/kangaru/patches/source.rbs +9 -0
  52. data/sig/kangaru/patches/symboliser.rbs +13 -0
  53. data/sig/kangaru/path_parser.rbs +19 -0
  54. data/sig/kangaru/paths.rbs +35 -0
  55. data/sig/kangaru/renderer.rbs +9 -0
  56. data/sig/kangaru/request.rbs +24 -0
  57. data/sig/kangaru/request_builder.rbs +21 -0
  58. data/sig/kangaru/router.rbs +26 -0
  59. data/sig/kangaru/validation/attribute_validator.rbs +21 -0
  60. data/sig/kangaru/validation/error.rbs +20 -0
  61. data/sig/kangaru/validators/required_validator.rbs +9 -0
  62. data/sig/kangaru/validators/validator.rbs +20 -0
  63. data/sig/kangaru.rbs +29 -0
  64. metadata +51 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04e8f14e4f41534168d56fdc09364a9507553658887f513a1536fe71f6a9c608
4
- data.tar.gz: 3af9ce12c3a133964cf66393f0d93339c37ae5329c3bd3ddcd65f53e1f224a28
3
+ metadata.gz: 5f81016147f4602231fda1758cc6064101872f31d56d65aa830d3917caef5fae
4
+ data.tar.gz: 117244d96c1de48b808bcd8a68810d1582d39f60e26969e393057297cb711363
5
5
  SHA512:
6
- metadata.gz: 6c9ee4ea2cf630d10e52d9a0a549f0ce77c5751c0469ca523baa91e15aa7eaa2e479e6120a683ad6cfb7aed8a6987cd7209d11a51a1503daa4910721718df1d8
7
- data.tar.gz: d7c959405a39a4086409f8e1a739643502ef102b662728dc1859e9bc3f8195cc576b9ee81f93135536141dbbd438e37047be08e1f15048fa18d7a32f1887a883
6
+ metadata.gz: c4eb18b51418ae6c2286f7091e18335e8d7f710bd405c36fa190ddf5ecbd0d3a55107e1e6ec25fc3dae5be46774e6531b692e2d1c207660a0aef4aa87eefc5f9
7
+ data.tar.gz: 0fa8ecd03c0ac6d392c3e4555e0edc62dac602814707e781b6bc971f20ca85cf968937bddb281cb8d7716de521dc0673672852c51a49858ba48a3b31faa8548e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kangaru (0.1.0)
4
+ kangaru (0.1.1)
5
5
  colorize (~> 1.1)
6
6
  erb (~> 4.0)
7
7
  sequel (~> 5.72)
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Kangaru is an open-source framework written in Ruby for building powerful and efficient command line applications. This project aims to make it easier for developers to create complex CLI programs with minimal effort, by providing a set of useful tools and libraries in a configurable ecosystem.
4
4
 
5
+ > Note: This software is currently in beta mode, meaning it may contain bugs and be subject to changes. Please exercise caution when using this software and report any issues you encounter. The first production-ready release of Kangaru will be version 0.2.0.
6
+
5
7
  ## Features
6
8
 
7
9
  - MVC architecture drawing heavy inspiration from Rails
data/Steepfile CHANGED
@@ -3,6 +3,8 @@ target :lib do
3
3
 
4
4
  check "lib"
5
5
 
6
+ ignore "lib/kangaru/initialisers/rspec*"
7
+
6
8
  configure_code_diagnostics do |hash|
7
9
  hash[Steep::Diagnostic::Ruby::FallbackAny] = nil
8
10
  hash[Steep::Diagnostic::Ruby::UnknownConstant] = :error
data/kangaru.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
 
13
13
  spec.files = Dir.chdir(__dir__) do
14
14
  `git ls-files`.split("\n").reject do |f|
15
- f == __FILE__ || f.match?(/\A(bin|sig|spec|\.git|\.github)/)
15
+ f == __FILE__ || f.match?(/\A(bin|spec|\.git|\.github)/)
16
16
  end
17
17
  end
18
18
  spec.bindir = "bin"
@@ -16,6 +16,10 @@ module Kangaru
16
16
  @config ||= Config.new
17
17
  end
18
18
 
19
+ def router
20
+ @router ||= Router.new(namespace:)
21
+ end
22
+
19
23
  # If called with no env, the config will be applied regardless of current
20
24
  # env. If multiple configure calls matching the current env are made, the
21
25
  # most recent calls will overwrite older changes.
@@ -39,7 +43,7 @@ module Kangaru
39
43
  def run!(*argv)
40
44
  request = RequestBuilder.new(argv).build
41
45
 
42
- Router.new(request, namespace:).resolve
46
+ router.resolve(request)
43
47
  end
44
48
 
45
49
  def_delegators :paths, :view_path
@@ -14,7 +14,7 @@ module Kangaru
14
14
  end
15
15
 
16
16
  def config
17
- Kangaru.application.config.for(self.class.configurator_name) ||
17
+ Kangaru.application!.config.for(self.class.configurator_name) ||
18
18
  raise("inferred configurator not set by application")
19
19
  end
20
20
  end
@@ -13,7 +13,7 @@ module Kangaru
13
13
  end
14
14
 
15
15
  def execute
16
- public_send(request.action)
16
+ return unless public_send(request.action)
17
17
 
18
18
  renderer_for(request.action.to_s).render(binding)
19
19
  end
@@ -30,7 +30,7 @@ module Kangaru
30
30
  private
31
31
 
32
32
  def view_path(file)
33
- Kangaru.application.view_path(self.class.path, file)
33
+ Kangaru.application!.view_path(self.class.path, file)
34
34
  end
35
35
 
36
36
  def renderer_for(file)
@@ -43,9 +43,9 @@ module Kangaru
43
43
  # within the application namespace by delegating const lookups to said
44
44
  # namespace if the constant is not in scope from the current class.
45
45
  def self.const_missing(const)
46
- return super unless Kangaru.application.namespace.const_defined?(const)
46
+ return super unless Kangaru.application!.namespace.const_defined?(const)
47
47
 
48
- Kangaru.application.namespace.const_get(const)
48
+ Kangaru.application!.namespace.const_get(const)
49
49
  end
50
50
 
51
51
  private_class_method :const_missing
@@ -31,7 +31,7 @@ module Kangaru
31
31
  Sequel::Migrator.run(handler, migration_path)
32
32
  end
33
33
 
34
- def_delegators :handler, :tables
34
+ def_delegators :handler, :rollback_on_exit, :tables, :transaction
35
35
 
36
36
  private
37
37
 
@@ -0,0 +1,18 @@
1
+ module Kangaru
2
+ module Initialisers
3
+ module RSpec
4
+ module KangaruHelper
5
+ def run_in_transaction(&block)
6
+ database = Kangaru.application&.database
7
+
8
+ return block.call if database.nil?
9
+
10
+ database.transaction do
11
+ block.call
12
+ database.rollback_on_exit
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,70 @@
1
+ module Kangaru
2
+ module Initialisers
3
+ module RSpec
4
+ module RequestHelper
5
+ extend ::RSpec::Matchers::DSL
6
+
7
+ attr_reader :request
8
+
9
+ def stub_output(&block)
10
+ stdout = $stdout
11
+ stderr = $stderr
12
+ $stdout = File.open(File::NULL, "w")
13
+ $stderr = File.open(File::NULL, "w")
14
+
15
+ block.call
16
+
17
+ $stdout = stdout
18
+ $stderr = stderr
19
+ end
20
+
21
+ def resolve(path, params:)
22
+ @request = Kangaru::Request.new(path:, params:)
23
+
24
+ Kangaru.application.router.resolve(request)
25
+ end
26
+
27
+ def view_path(name)
28
+ Kangaru.application!.view_path(described_class.path, name.to_s)
29
+ end
30
+
31
+ matcher :render_template do |name|
32
+ supports_block_expectations
33
+
34
+ match do |action|
35
+ renderer = instance_double(Kangaru::Renderer, render: nil)
36
+ allow(Kangaru::Renderer).to receive(:new).and_return(renderer)
37
+ expect(Kangaru::Renderer).not_to have_received(:new)
38
+
39
+ action.call
40
+
41
+ expect(Kangaru::Renderer)
42
+ .to have_received(:new)
43
+ .with(view_path(name))
44
+ .once
45
+
46
+ expect(renderer)
47
+ .to have_received(:render)
48
+ .once
49
+ end
50
+ end
51
+ end
52
+
53
+ if Object.const_defined?(:RSpec)
54
+ ::RSpec.configure do |config|
55
+ file_path = %r{spec/.*/controllers/}
56
+
57
+ config.define_derived_metadata(file_path:) do |metadata|
58
+ metadata[:type] = :request
59
+ end
60
+
61
+ config.include RequestHelper, type: :request
62
+
63
+ config.around(type: :request) do |spec|
64
+ stub_output { spec.run }
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -2,8 +2,14 @@ module Kangaru
2
2
  module Initialisers
3
3
  module RSpec
4
4
  if Object.const_defined?(:RSpec)
5
- ::RSpec.configure do
5
+ ::RSpec.configure do |config|
6
6
  Kangaru.env = :test
7
+
8
+ config.include KangaruHelper
9
+
10
+ config.around do |spec|
11
+ run_in_transaction { spec.run }
12
+ end
7
13
  end
8
14
  end
9
15
  end
@@ -1,23 +1,23 @@
1
1
  module Kangaru
2
2
  module InjectedMethods
3
3
  def run!(*argv)
4
- Kangaru.application.run!(*argv)
4
+ Kangaru.application!.run!(*argv)
5
5
  end
6
6
 
7
7
  def config
8
- Kangaru.application.config
8
+ Kangaru.application!.config
9
9
  end
10
10
 
11
11
  def configure(env = nil, &)
12
- Kangaru.application.configure(env, &)
12
+ Kangaru.application!.configure(env, &)
13
13
  end
14
14
 
15
15
  def apply_config!
16
- Kangaru.application.apply_config!
16
+ Kangaru.application!.apply_config!
17
17
  end
18
18
 
19
19
  def database
20
- Kangaru.application.database
20
+ Kangaru.application!.database
21
21
  end
22
22
  end
23
23
  end
@@ -5,15 +5,16 @@ module Kangaru
5
5
 
6
6
  attr_reader :request, :namespace
7
7
 
8
- def initialize(request, namespace: Object)
9
- @request = request
8
+ def initialize(namespace: Object)
10
9
  @namespace = namespace
10
+ end
11
+
12
+ def resolve(request)
13
+ @request = request
11
14
 
12
15
  validate_controller_defined!
13
16
  validate_action_defined!
14
- end
15
17
 
16
- def resolve
17
18
  controller_class.new(request).execute
18
19
  end
19
20
 
@@ -1,3 +1,3 @@
1
1
  module Kangaru
2
- VERSION = "0.1.0".freeze
2
+ VERSION = "0.1.1".freeze
3
3
  end
data/lib/kangaru.rb CHANGED
@@ -29,10 +29,10 @@ module Kangaru
29
29
  end
30
30
 
31
31
  class << self
32
- attr_writer :application
32
+ attr_accessor :application
33
33
 
34
- def application
35
- @application || raise("application not set")
34
+ def application!
35
+ application || raise("application not set")
36
36
  end
37
37
 
38
38
  def env=(value)
data/sig/class.rbs ADDED
@@ -0,0 +1,3 @@
1
+ class Class
2
+ def class_eval: ?{ [self: Class]-> void } -> void | ...
3
+ end
@@ -0,0 +1,34 @@
1
+ module Kangaru
2
+ class Application
3
+ extend Forwardable
4
+
5
+ attr_reader paths: Paths
6
+ attr_reader namespace: Module
7
+ attr_reader config: Config
8
+ attr_reader database: Database?
9
+ attr_reader router: Router
10
+
11
+ def initialize: (source: String, namespace: Module) -> void
12
+
13
+ def configure: (?Symbol?) { (Config) -> void } -> void
14
+
15
+ def configured?: -> bool
16
+
17
+ def apply_config!: -> void
18
+
19
+ def run!: (*String) -> void
20
+
21
+ # Delegated to paths
22
+ def view_path: (*String, ?ext: Symbol?) -> Pathname
23
+
24
+ private
25
+
26
+ @configured: bool
27
+
28
+ def current_env?: (Symbol?) -> bool
29
+
30
+ attr_reader autoloader: Zeitwerk::Loader
31
+
32
+ def setup_database!: -> Database?
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ module Kangaru
2
+ class ArgumentParser
3
+ attr_reader tokens: Array[String]
4
+
5
+ def initialize: (*String) -> void
6
+
7
+ def parse: -> Hash[Symbol, untyped]
8
+
9
+ private
10
+
11
+ def grouped_argument_tokens: -> Array[Array[String]]
12
+
13
+ def parse_key: (String) -> Symbol
14
+
15
+ def parse_value: (Array[untyped]) -> untyped
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module Kangaru
2
+ class Component
3
+ def render: -> void
4
+
5
+ private
6
+
7
+ def view_file: -> Pathname
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ module Kangaru
2
+ module Concerns
3
+ module AttributesConcern
4
+ extend Concern
5
+
6
+ module ClassMethods
7
+ def attributes: -> Array[Symbol]
8
+
9
+ def defaults: -> Hash[Symbol, untyped]
10
+
11
+ def set_default: (**untyped) -> void
12
+
13
+ @defaults: Hash[Symbol, untyped]
14
+ end
15
+
16
+ extend ClassMethods
17
+
18
+ attr_reader defaults: Hash[Symbol, untyped]
19
+
20
+ def instance_methods: -> Array[Symbol]
21
+
22
+ def initialize: (**untyped) -> void
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module Kangaru
2
+ module Concerns
3
+ module Concern : Module
4
+ @included: untyped
5
+
6
+ def append_features: (untyped) -> void
7
+
8
+ def class_methods: { [self: singleton(Class)] -> void } -> void
9
+
10
+ def included: (?untyped?) ?{ -> void } -> void
11
+
12
+ def evaluate_concern_blocks!: (untyped) -> void
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Kangaru
2
+ module Concerns
3
+ module Configurable
4
+ extend Concern
5
+ extend ClassMethods
6
+
7
+ module ClassMethods
8
+ def configurator_name: -> String
9
+ end
10
+
11
+ def name: -> String
12
+ def config: [C < Configurators::Configurator] -> C
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module Kangaru
2
+ module Concerns
3
+ module Validatable
4
+ type validations = Hash[Symbol, Hash[Symbol, untyped]]
5
+
6
+ extend Concern
7
+ extend ClassMethods
8
+
9
+ attr_reader validation_rules: validations
10
+
11
+ module ClassMethods
12
+ attr_reader validation_rules: validations
13
+
14
+ def validates: (Symbol, **untyped) -> void
15
+ end
16
+
17
+ attr_reader errors: Array[Validation::Error]
18
+
19
+ def validate: -> void
20
+
21
+ def valid?: -> bool
22
+
23
+ private
24
+
25
+ def validator_for: (Symbol) -> Validation::AttributeValidator
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ module Kangaru
2
+ class Config
3
+ type configurator = Configurators::Configurator
4
+
5
+ attr_reader configurators: Hash[Symbol, configurator]
6
+
7
+ def initialize: -> void
8
+
9
+ def serialise: -> Hash[Symbol, Hash[Symbol, untyped]]
10
+
11
+ def import_external_config!: -> void
12
+
13
+ def for: (String) -> untyped
14
+
15
+ # Configurators
16
+ attr_reader application: Configurators::ApplicationConfigurator
17
+ attr_reader database: Configurators::DatabaseConfigurator
18
+ attr_reader external: Configurators::ExternalConfigurator
19
+ attr_reader request: Configurators::RequestConfigurator
20
+
21
+ private
22
+
23
+ def set_configurators!: -> Hash[Symbol, configurator]
24
+
25
+ def external_config_exists?: -> bool
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ module Kangaru
2
+ module Configurators
3
+ class ApplicationConfigurator < Configurator
4
+ attr_accessor config_path: String
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ module Kangaru
2
+ module Configurators
3
+ class Configurator
4
+ include Concerns::AttributesConcern
5
+ extend Concerns::AttributesConcern::ClassMethods
6
+
7
+ def self.key: -> Symbol
8
+
9
+ def self.name: -> String
10
+
11
+ def serialise: -> Hash[Symbol, untyped]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Kangaru
2
+ module Configurators
3
+ class DatabaseConfigurator < Configurator
4
+ attr_accessor adaptor: Symbol
5
+ attr_accessor path: String
6
+ attr_accessor migration_path: String
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module Kangaru
2
+ module Configurators
3
+ class ExternalConfigurator < OpenConfigurator
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ module Kangaru
2
+ module Configurators
3
+ class OpenConfigurator < Configurator
4
+ def self.from_yaml_file: (String) -> instance
5
+
6
+ private
7
+
8
+ def set_accessors!: (**untyped) -> void
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Kangaru
2
+ module Configurators
3
+ class RequestConfigurator < Configurator
4
+ attr_accessor default_controller: (String | Symbol | singleton(Controller))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Kangaru
2
+ module Configurators
3
+ BASE_CONFIGURATORS: Array[singleton(Configurator)]
4
+
5
+ def self.classes: -> Array[singleton(Configurator)]
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ module Kangaru
2
+ class Controller
3
+ extend Forwardable
4
+
5
+ SUFFIX: String
6
+
7
+ attr_reader request: Request
8
+
9
+ def initialize: (Request) -> void
10
+
11
+ def execute: -> void
12
+
13
+ def self.path: -> String
14
+
15
+ def params: -> Hash[Symbol, untyped]
16
+
17
+ private
18
+
19
+ def view_path: (String) -> Pathname
20
+
21
+ def renderer_for: (String) -> Renderer
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ module Kangaru
2
+ class Database
3
+ extend Forwardable
4
+
5
+ include Concerns::AttributesConcern
6
+ extend Concerns::AttributesConcern::ClassMethods
7
+
8
+ PLUGINS: Array[Symbol]
9
+
10
+ attr_accessor adaptor: Symbol
11
+ attr_accessor path: String
12
+ attr_accessor migration_path: String
13
+
14
+ attr_reader handler: Sequel::Database
15
+
16
+ def setup!: -> void
17
+
18
+ def migrate!: -> void
19
+
20
+ # Delegated to handler
21
+ def rollback_on_exit: -> void
22
+ def tables: -> Array[Symbol]
23
+ def transaction: { -> void } -> void
24
+
25
+ private
26
+
27
+ def migrations_exist?: -> bool
28
+
29
+ def setup_sqlite!: -> Sequel::Database
30
+ end
31
+ end
@@ -0,0 +1,6 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class ClassInflector < Inflector
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class ConstantInflector < ClassInflector
4
+ LAST_WORD: Regexp
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class Constantiser
4
+ attr_reader string: String
5
+
6
+ def self.constantise: (String, ?root: Module) -> untyped
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class HumanInflector < Inflector
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,47 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class Inflector
4
+ type token_groups = Array[Array[String]]
5
+
6
+ extend InflectorMacros
7
+
8
+ DEFAULT_GROUP_JOINER: String
9
+
10
+ attr_reader string: String
11
+
12
+ def initialize: (String) -> void
13
+
14
+ def inflect: -> String
15
+
16
+ def self.inflect: (String) -> String
17
+
18
+ private
19
+
20
+ attr_reader tokeniser: Tokeniser
21
+
22
+ def class_attribute: (Symbol) -> untyped
23
+
24
+ def input_filter: -> untyped
25
+
26
+ def token_transformer: -> untyped
27
+
28
+ def token_joiner: -> untyped
29
+
30
+ def group_joiner: -> untyped
31
+
32
+ def post_processor: -> untyped
33
+
34
+ def filter_input: (String) -> String
35
+
36
+ def transform_and_join_tokens: (Array[Array[String]]) -> Array[String]
37
+
38
+ def transform_token: (String) -> String
39
+
40
+ def join_tokens: (Array[String]) -> String
41
+
42
+ def join_groups: (Array[String]) -> String
43
+
44
+ def post_process: (String) -> String
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,23 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ module InflectorMacros
4
+ @input_filter: untyped
5
+ @token_transformer: untyped
6
+ @token_joiner: untyped
7
+ @group_joiner: untyped
8
+ @post_processor: untyped
9
+
10
+ def inherited: (Class) -> void
11
+
12
+ def filter_input_with: (Regexp) -> void
13
+
14
+ def transform_tokens_with: (?Symbol?) ?{ (String) -> String } -> void
15
+
16
+ def join_tokens_with: (String) -> void
17
+
18
+ def join_groups_with: (String) -> void
19
+
20
+ def post_process_with: (?Symbol?) ?{ (String) -> String } -> void
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class PathInflector < Inflector
4
+ def inflect: (?with_ext: String?) -> String
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class ScreamingSnakecaseInflector < SnakecaseInflector
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class SnakecaseInflector < Inflector
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,14 @@
1
+ module Kangaru
2
+ module Inflectors
3
+ class Tokeniser
4
+ GROUP_DELIMITER: Regexp
5
+ TOKEN_DELIMITER: Regexp
6
+
7
+ attr_reader string: String
8
+
9
+ def initialize: (String) -> void
10
+
11
+ def split: -> Array[Array[String]]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Kangaru
2
+ module Initialiser
3
+ module InjectedMethods
4
+ include Kangaru::_ApplicationMethods
5
+ end
6
+
7
+ def self.extended: (Module) -> void
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ module Kangaru
2
+ module Initialisers
3
+ module RSpec
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ module Kangaru
2
+ module InjectedMethods
3
+ interface _InjectedMethods
4
+ def run!: (*String) -> void
5
+
6
+ def config: -> Config
7
+
8
+ def configure: (?Symbol?) { (Config) -> void } -> void
9
+
10
+ def apply_config!: -> void
11
+
12
+ def database: -> Database?
13
+ end
14
+
15
+ include _InjectedMethods
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module Kangaru
2
+ # This is a hacky fix to ensure that the definition of Model via Class.new is
3
+ # typed to be the same as if it was called with `class Model; end`.
4
+ # This is to prevent the inherited hook trying to find a `models` database
5
+ # table when Sequel::Model is inherited in the conventional way.
6
+ class Class
7
+ def self.new: (untyped) { -> void } -> singleton(Model)
8
+ end
9
+
10
+ class Model < Sequel::Model
11
+ include Concerns::Validatable
12
+ extend Concerns::Validatable::ClassMethods
13
+
14
+ def self.enum: (Symbol, **Integer) -> void
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ module Kangaru
2
+ module Patches
3
+ module Constantise : String
4
+ class ::String
5
+ def constantise: (?root: Module) -> untyped
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module Kangaru
2
+ module Patches
3
+ module Inflections : String
4
+ class ::String
5
+ def to_class_name: -> String
6
+
7
+ def to_constant_name: -> String
8
+
9
+ def to_snakecase: -> String
10
+
11
+ def to_humanised: -> String
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module Kangaru
2
+ module Patches
3
+ module Source : Module
4
+ class ::Module
5
+ def source: -> String
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ module Kangaru
2
+ module Patches
3
+ module Symboliser : Enumerable[untyped]
4
+ class ::Hash[unchecked out K, unchecked out V]
5
+ def symbolise: -> Hash[Symbol, untyped]
6
+ end
7
+
8
+ class Array[unchecked out Elem]
9
+ def symbolise: -> Hash[Symbol, untyped]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module Kangaru
2
+ class PathParser
3
+ attr_reader path: String
4
+
5
+ def initialize: (String) -> void
6
+
7
+ def controller: -> String?
8
+
9
+ def action: -> Symbol?
10
+
11
+ def id: -> Integer?
12
+
13
+ private
14
+
15
+ MATCHERS: Hash[Symbol, Regexp]
16
+
17
+ def match: (Symbol, ?cast: Symbol) -> untyped
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ module Kangaru
2
+ class Paths
3
+ attr_reader source: Pathname
4
+ attr_reader dir: Pathname
5
+ attr_reader name: String
6
+
7
+ def initialize: (source: String) -> void
8
+
9
+ def gem_path: (*String, ?ext: Symbol?) -> Pathname
10
+
11
+ def lib_path: (*String, ?ext: Symbol?) -> Pathname
12
+
13
+ def path: (*String, ?ext: Symbol?) -> Pathname
14
+
15
+ def view_path: (*String, ?ext: Symbol?) -> Pathname
16
+
17
+ def collapsed_dirs: -> Array[String]
18
+
19
+ private
20
+
21
+ MODELS_DIRNAME: String
22
+ VIEWS_DIRNAME: String
23
+ CONTROLLERS_DIRNAME: String
24
+
25
+ attr_reader gem_dir: Pathname
26
+ attr_reader lib_dir: Pathname
27
+ attr_reader app_dir: Pathname
28
+
29
+ attr_reader models_dir: Pathname
30
+ attr_reader views_dir: Pathname
31
+ attr_reader controllers_dir: Pathname
32
+
33
+ def build_path: (*String, dir: Pathname, ext: Symbol?) -> Pathname
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module Kangaru
2
+ class Renderer
3
+ attr_reader path: Pathname
4
+
5
+ def initialize: (Pathname) -> void
6
+
7
+ def render: (Binding) -> void
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ module Kangaru
2
+ class Request
3
+ include Concerns::Configurable
4
+
5
+ DEFAULT_CONTROLLER: String
6
+
7
+ DEFAULT_ACTION: Symbol
8
+
9
+ attr_reader path: String
10
+ attr_reader params: Hash[Symbol, untyped]
11
+
12
+ def initialize: (path: String, params: Hash[Symbol, untyped]) -> void
13
+
14
+ def controller: -> String
15
+
16
+ def action: -> Symbol
17
+
18
+ private
19
+
20
+ attr_reader path_parser: PathParser
21
+
22
+ def default_controller: -> String
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ module Kangaru
2
+ class RequestBuilder
3
+ ARGUMENT_TOKEN: Regexp
4
+
5
+ attr_reader tokens: Array[String]
6
+
7
+ def initialize: (Array[String]) -> void
8
+
9
+ def build: -> Request
10
+
11
+ private
12
+
13
+ def path: -> String
14
+
15
+ def params: -> Hash[Symbol, untyped]
16
+
17
+ def path_tokens: -> Array[String]
18
+
19
+ def param_tokens: -> Array[String]
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ module Kangaru
2
+ class Router
3
+ extend Forwardable
4
+
5
+ attr_reader request: Request
6
+ attr_reader namespace: Module
7
+
8
+ def initialize: (?namespace: Module) -> void
9
+
10
+ def resolve: (Request) -> void
11
+
12
+ private
13
+
14
+ @controller_class: untyped
15
+
16
+ # Delegated to command
17
+ def controller_name: -> String
18
+ def action: -> Symbol
19
+
20
+ def controller_class: -> untyped
21
+
22
+ def validate_controller_defined!: -> void
23
+
24
+ def validate_action_defined!: -> void
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ module Kangaru
2
+ module Validation
3
+ class AttributeValidator
4
+ attr_reader model: untyped
5
+ attr_reader attribute: Symbol
6
+
7
+ def initialize: (model: untyped, attribute: Symbol) -> void
8
+
9
+ def validate: (Symbol, **untyped) -> void
10
+
11
+ private
12
+
13
+ def validator_name: (Symbol) -> String
14
+
15
+ def load_validator: (
16
+ validator: Symbol,
17
+ params: Hash[Symbol, untyped]
18
+ ) -> Validators::Validator
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module Kangaru
2
+ module Validation
3
+ class Error
4
+ MESSAGES: Hash[Symbol, String]
5
+
6
+ attr_reader attribute: Symbol
7
+ attr_reader type: Symbol
8
+
9
+ def initialize: (attribute: Symbol, type: Symbol) -> void
10
+
11
+ def full_message: -> String
12
+
13
+ private
14
+
15
+ def human_attribute: -> String
16
+
17
+ def message: -> String
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module Kangaru
2
+ module Validators
3
+ class RequiredValidator < Validator
4
+ private
5
+
6
+ def value_missing?: -> bool
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ module Kangaru
2
+ module Validators
3
+ class Validator
4
+ attr_reader model: untyped
5
+ attr_reader attribute: Symbol
6
+ attr_reader params: Hash[Symbol, untyped]
7
+ attr_reader value: untyped
8
+
9
+ def initialize: (
10
+ model: untyped,
11
+ attribute: Symbol,
12
+ params: Hash[Symbol, untyped]
13
+ ) -> void
14
+
15
+ def validate: -> void
16
+
17
+ def add_error!: (Symbol) -> void
18
+ end
19
+ end
20
+ end
data/sig/kangaru.rbs ADDED
@@ -0,0 +1,29 @@
1
+ module Kangaru
2
+ VERSION: String
3
+
4
+ COLLAPSED_DIRS: Array[String]
5
+ DEFAULT_ENV: Symbol
6
+ INFLECTIONS: Hash[String, String]
7
+
8
+ extend ClassMethods
9
+
10
+ module ClassMethods
11
+ @loader: Zeitwerk::Loader
12
+
13
+ attr_accessor application: Application?
14
+ attr_accessor env: Symbol
15
+
16
+ def application!: -> Application
17
+
18
+ def env?: (Symbol) -> bool
19
+
20
+ def eager_load: (Module) -> void
21
+
22
+ def test?: -> bool
23
+ end
24
+
25
+ # Included in target applications that extend Kangaru::Initialiser.
26
+ interface _ApplicationMethods
27
+ include InjectedMethods::_InjectedMethods
28
+ end
29
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kangaru
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Welham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-07 00:00:00.000000000 Z
11
+ date: 2023-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -128,6 +128,8 @@ files:
128
128
  - lib/kangaru/inflectors/tokeniser.rb
129
129
  - lib/kangaru/initialiser.rb
130
130
  - lib/kangaru/initialisers/rspec.rb
131
+ - lib/kangaru/initialisers/rspec/kangaru_helper.rb
132
+ - lib/kangaru/initialisers/rspec/request_helper.rb
131
133
  - lib/kangaru/injected_methods.rb
132
134
  - lib/kangaru/model.rb
133
135
  - lib/kangaru/patches/constantise.rb
@@ -147,6 +149,53 @@ files:
147
149
  - lib/kangaru/version.rb
148
150
  - rbs_collection.lock.yaml
149
151
  - rbs_collection.yaml
152
+ - sig/class.rbs
153
+ - sig/kangaru.rbs
154
+ - sig/kangaru/application.rbs
155
+ - sig/kangaru/argument_parser.rbs
156
+ - sig/kangaru/components/component.rbs
157
+ - sig/kangaru/concerns/attributes_concern.rbs
158
+ - sig/kangaru/concerns/concern.rbs
159
+ - sig/kangaru/concerns/configurable.rbs
160
+ - sig/kangaru/concerns/validatable.rbs
161
+ - sig/kangaru/config.rbs
162
+ - sig/kangaru/configurators.rbs
163
+ - sig/kangaru/configurators/application_configurator.rbs
164
+ - sig/kangaru/configurators/configurator.rbs
165
+ - sig/kangaru/configurators/database_configurator.rbs
166
+ - sig/kangaru/configurators/external_configurator.rbs
167
+ - sig/kangaru/configurators/open_configurator.rbs
168
+ - sig/kangaru/configurators/request_configurator.rbs
169
+ - sig/kangaru/controller.rbs
170
+ - sig/kangaru/database.rbs
171
+ - sig/kangaru/inflectors/class_inflector.rbs
172
+ - sig/kangaru/inflectors/constant_inflector.rbs
173
+ - sig/kangaru/inflectors/constantiser.rbs
174
+ - sig/kangaru/inflectors/human_inflector.rbs
175
+ - sig/kangaru/inflectors/inflector.rbs
176
+ - sig/kangaru/inflectors/inflector_macros.rbs
177
+ - sig/kangaru/inflectors/path_inflector.rbs
178
+ - sig/kangaru/inflectors/screaming_snakecase_inflector.rbs
179
+ - sig/kangaru/inflectors/snakecase_inflector.rbs
180
+ - sig/kangaru/inflectors/tokeniser.rbs
181
+ - sig/kangaru/initialiser.rbs
182
+ - sig/kangaru/initialisers/rspec.rbs
183
+ - sig/kangaru/injected_methods.rbs
184
+ - sig/kangaru/model.rbs
185
+ - sig/kangaru/patches/constantise.rbs
186
+ - sig/kangaru/patches/inflections.rbs
187
+ - sig/kangaru/patches/source.rbs
188
+ - sig/kangaru/patches/symboliser.rbs
189
+ - sig/kangaru/path_parser.rbs
190
+ - sig/kangaru/paths.rbs
191
+ - sig/kangaru/renderer.rbs
192
+ - sig/kangaru/request.rbs
193
+ - sig/kangaru/request_builder.rbs
194
+ - sig/kangaru/router.rbs
195
+ - sig/kangaru/validation/attribute_validator.rbs
196
+ - sig/kangaru/validation/error.rbs
197
+ - sig/kangaru/validators/required_validator.rbs
198
+ - sig/kangaru/validators/validator.rbs
150
199
  homepage:
151
200
  licenses:
152
201
  - MIT