rrx_dev 0.1.2

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.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # RRXDev
2
+
3
+ Opinionated core development dependencies and configuration for Ruby on Rails projects
4
+
5
+ ## Installation
6
+
7
+ Install the gem and add to the application's Gemfile by executing:
8
+
9
+ $ bundle add rrx_dev
10
+
11
+ If bundler is not being used to manage dependencies, install the gem by executing:
12
+
13
+ $ gem install rrx_dev
14
+
15
+ After installation, instrument your project by running `rrx_dev_setup`
16
+
17
+ ```shell
18
+ # For Rails apps
19
+ rrx_dev_setup app
20
+
21
+ # For Rails gems
22
+ rrx_dev_setup gem
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ TODO
28
+
29
+ ## Development
30
+
31
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
32
+
33
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
34
+
35
+ ## Contributing
36
+
37
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dan-drew/rrx_dev. 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/dan-drew/rrx_dev/blob/main/CODE_OF_CONDUCT.md).
38
+
39
+ ## License
40
+
41
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
42
+
43
+ ## Code of Conduct
44
+
45
+ Everyone interacting in the RrxDev project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/dan-drew/rrx_dev/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,142 @@
1
+ ##
2
+ # Extensions
3
+ require:
4
+ - rubocop-rails
5
+
6
+ AllCops:
7
+ SuggestExtensions: false
8
+ TargetRubyVersion: 3.1.0
9
+ Exclude:
10
+ - 'xspecx/**/*'
11
+ - 'bin/**/*'
12
+ - 'lib/**/version.rb'
13
+ - 'Gemfile'
14
+ - 'db/schema.rb'
15
+
16
+ ##
17
+ # Style
18
+ Style/Documentation:
19
+ Enabled: false
20
+
21
+ Style/MultilineBlockChain:
22
+ Enabled: false
23
+
24
+ Style/FrozenStringLiteralComment:
25
+ Enabled: false
26
+
27
+ Style/FormatString:
28
+ Enabled: false
29
+
30
+ Style/LambdaCall:
31
+ Enabled: false
32
+
33
+ Style/EmptyCaseCondition:
34
+ Enabled: false
35
+
36
+ Style/SymbolArray:
37
+ Enabled: false
38
+
39
+ Style/RescueStandardError:
40
+ Enabled: false
41
+
42
+ Style/GuardClause:
43
+ Enabled: false
44
+
45
+ Style/ClassAndModuleChildren:
46
+ Enabled: false
47
+
48
+ Style/RegexpLiteral:
49
+ Enabled: false
50
+
51
+ Style/FormatStringToken:
52
+ Enabled: false
53
+
54
+ Style/PerlBackrefs:
55
+ Enabled: false
56
+
57
+ Style/MultilineIfModifier:
58
+ Enabled: false
59
+
60
+ Style/RescueModifier:
61
+ Enabled: false
62
+
63
+ Style/MultilineTernaryOperator:
64
+ Enabled: false
65
+
66
+ ##
67
+ # Layout
68
+ Layout/HashAlignment:
69
+ EnforcedHashRocketStyle: table
70
+ EnforcedColonStyle: table
71
+
72
+ Layout/ArgumentAlignment:
73
+ Enabled: false
74
+
75
+ Layout/MultilineMethodCallIndentation:
76
+ Enabled: false
77
+
78
+ Layout/FirstArgumentIndentation:
79
+ Enabled: false
80
+
81
+ Layout/FirstHashElementIndentation:
82
+ Enabled: false
83
+
84
+ ##
85
+ # Lint
86
+ Lint/AmbiguousBlockAssociation:
87
+ Exclude:
88
+ - 'spec/**/*'
89
+
90
+ Lint/AmbiguousOperator:
91
+ Enabled: false
92
+
93
+ ##
94
+ # Metric
95
+ Metrics/BlockLength:
96
+ Enabled: false
97
+
98
+ Metrics/ClassLength:
99
+ Enabled: false
100
+
101
+ Metrics/MethodLength:
102
+ Enabled: false
103
+
104
+ Metrics/ParameterLists:
105
+ Max: 10
106
+
107
+ Metrics/PerceivedComplexity:
108
+ Max: 10
109
+
110
+ Metrics/AbcSize:
111
+ Max: 25
112
+
113
+ Metrics/CyclomaticComplexity:
114
+ Max: 10
115
+
116
+ ##
117
+ # Naming
118
+ Naming/MethodParameterName:
119
+ MinNameLength: 1
120
+
121
+ Naming/AccessorMethodName:
122
+ Enabled: false
123
+
124
+ ##
125
+ # Rails
126
+ Rails/DynamicFindBy:
127
+ Enabled: false
128
+
129
+ Rails/SkipsModelValidations:
130
+ Enabled: false
131
+
132
+ Rails/CreateTableWithTimestamps:
133
+ Enabled: false
134
+
135
+ Rails/HasAndBelongsToMany:
136
+ Enabled: false
137
+
138
+ ##
139
+ # Security
140
+ Security/Eval:
141
+ Exclude:
142
+ - 'Gemfile'
data/exe/rrx_dev_setup ADDED
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'thor'
4
+ require 'pathname'
5
+
6
+ class Setup < Thor
7
+ include Thor::Actions
8
+
9
+ GEM_SPEC_APP_NAME = 'dummy'
10
+ GEM_SPEC_APP_ROOT = 'spec/dummy'
11
+
12
+ def self.exit_on_failure?
13
+ true
14
+ end
15
+
16
+ def self.source_root
17
+ File.join(__dir__, 'sources')
18
+ end
19
+
20
+ desc 'app', 'Initialize a new Rails app'
21
+
22
+ def app
23
+ editorconfig
24
+ rubocop
25
+ rspec
26
+ environment
27
+ instructions
28
+ end
29
+
30
+ desc 'gem', 'Initialize a new Rails gem'
31
+
32
+ def gem
33
+ @gem = true
34
+ app
35
+ end
36
+
37
+ private
38
+
39
+ def gem?
40
+ @gem
41
+ end
42
+
43
+ def editorconfig
44
+ copy_file 'editorconfig', '.editorconfig'
45
+ end
46
+
47
+ def rubocop
48
+ copy_file 'rubocop.yml', '.rubocop.yml'
49
+ end
50
+
51
+ def app_root
52
+ @app_root ||= Pathname(gem? ? GEM_SPEC_APP_ROOT : '')
53
+ end
54
+
55
+ def app_config
56
+ @app_config ||= app_root.join('config')
57
+ end
58
+
59
+ def app_environments
60
+ @app_environments ||= app_config.join('environments')
61
+ end
62
+
63
+ def environment
64
+ directory 'config', app_config
65
+ end
66
+
67
+ def rspec
68
+ copy_file 'rspec', '.rspec'
69
+ empty_directory 'spec/factories'
70
+ empty_directory 'spec/support'
71
+ empty_directory 'spec/models'
72
+ empty_directory 'spec/requests'
73
+ copy_file 'spec/spec_helper.rb'
74
+
75
+ # Override rails_helper and make sure it loads the Rails environment for the app
76
+ # or the gem's spec dummy app
77
+ copy_file 'spec/rails_helper.rb' do |content|
78
+ content.sub '../config/environment', "../#{app_config}/environment"
79
+ end
80
+
81
+ create_spec_app if gem?
82
+ end
83
+
84
+ ##
85
+ # Create a dummy Rails app for testing
86
+ def create_spec_app
87
+ in_root do
88
+ unless Dir.exist?(GEM_SPEC_APP_ROOT)
89
+ inside('spec') do
90
+ run 'rails new --api -G --skip-docker -M --skip-active-job --skip-bootsnap -C -A -J -T -B dummy'
91
+ end
92
+ %w[development test production].each do |environment|
93
+ remove_file app_environments.join("#{environment}.rb")
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ def instructions
100
+ puts <<~DOC
101
+
102
+ ## Fixing/linting with Rubocop
103
+
104
+ ### RubyMine: Run Rubocop autocorrect on save
105
+
106
+ 1. Go to File > Settings > Editor > Inspections
107
+ 1. Search for 'Rubocop'
108
+ 1. Check the box next to "Run 'rubocop -a' on save"
109
+
110
+ ref: https://www.jetbrains.com/help/ruby/rubocop.html
111
+
112
+ DOC
113
+ end
114
+ end
115
+
116
+ Setup.start
@@ -0,0 +1,32 @@
1
+ require 'active_support/core_ext/integer/time'
2
+
3
+ Rails.application.configure do
4
+ config.cache_classes = false
5
+ config.eager_load = false
6
+ config.consider_all_requests_local = true
7
+
8
+ # Enable/disable caching. By default caching is disabled.
9
+ # Run rails dev:cache to toggle caching.
10
+ if Rails.root.join('tmp/caching-dev.txt').exist?
11
+ config.cache_store = :memory_store
12
+ config.public_file_server.headers = {
13
+ 'Cache-Control' => "public, max-age=#{2.days.to_i}"
14
+ }
15
+ else
16
+ config.action_controller.perform_caching = false
17
+ config.cache_store = :null_store
18
+ end
19
+
20
+ # Print deprecation notices to the Rails logger.
21
+ config.active_support.deprecation = :log
22
+
23
+ # Raise exceptions for disallowed deprecations.
24
+ config.active_support.disallowed_deprecation = :raise
25
+
26
+ # Tell Active Support which deprecation messages to disallow.
27
+ config.active_support.disallowed_deprecation_warnings = []
28
+
29
+ # Use an evented file watcher to asynchronously detect changes in source code,
30
+ # routes, locales, etc. This feature depends on the listen gem.
31
+ config.file_watcher = ActiveSupport::EventedFileUpdateChecker
32
+ end
@@ -0,0 +1,16 @@
1
+ require 'active_support/core_ext/integer/time'
2
+
3
+ Rails.application.configure do
4
+ config.cache_classes = true
5
+ config.eager_load = true
6
+ config.consider_all_requests_local = false
7
+
8
+ config.cache_store = :memory_store, { size: 64.megabytes }
9
+
10
+ config.active_support.deprecation = :notify
11
+ config.active_support.disallowed_deprecation = :log
12
+ config.active_support.disallowed_deprecation_warnings = []
13
+
14
+ # Do not dump schema after migrations.
15
+ config.active_record.dump_schema_after_migration = false
16
+ end
@@ -0,0 +1,19 @@
1
+ require 'active_support/core_ext/integer/time'
2
+
3
+ # The test environment is used exclusively to run your application's
4
+ # test suite. You never need to work with it otherwise. Remember that
5
+ # your test database is "scratch space" for the test suite and is wiped
6
+ # and recreated between test runs. Don't rely on the data there!
7
+
8
+ Rails.application.configure do
9
+ config.cache_classes = false
10
+ config.eager_load = false
11
+ config.consider_all_requests_local = true
12
+ config.cache_store = :null_store
13
+ config.action_dispatch.show_exceptions = false
14
+ config.active_support.deprecation = :stderr
15
+ config.active_support.disallowed_deprecation = :raise
16
+ config.active_support.disallowed_deprecation_warnings = []
17
+ config.action_controller.perform_caching = false
18
+ config.action_controller.allow_forgery_protection = false
19
+ end
@@ -0,0 +1,109 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ indent_size = 2
7
+ indent_style = space
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+ max_line_length = 120
11
+ tab_width = 2
12
+ ij_continuation_indent_size = 4
13
+ ij_formatter_off_tag = @formatter:off
14
+ ij_formatter_on_tag = @formatter:on
15
+ ij_formatter_tags_enabled = true
16
+ ij_smart_tabs = false
17
+ ij_visual_guides =
18
+ ij_wrap_on_typing = false
19
+
20
+ [.editorconfig]
21
+ ij_editorconfig_align_group_field_declarations = false
22
+ ij_editorconfig_space_after_colon = false
23
+ ij_editorconfig_space_after_comma = true
24
+ ij_editorconfig_space_before_colon = false
25
+ ij_editorconfig_space_before_comma = false
26
+ ij_editorconfig_spaces_around_assignment_operators = true
27
+
28
+ [{*.bash,*.sh,*.zsh}]
29
+ ij_shell_binary_ops_start_line = false
30
+ ij_shell_keep_column_alignment_padding = false
31
+ ij_shell_minify_program = false
32
+ ij_shell_redirect_followed_by_space = false
33
+ ij_shell_switch_cases_indented = false
34
+ ij_shell_use_unix_line_separator = true
35
+
36
+ [{*.gemspec,*.jbuilder,*.rake,*.rb,*.rbi,*.rbw,*.ru,*.thor,.simplecov,capfile,gemfile,guardfile,isolate,rakefile,steepfile,vagrantfile}]
37
+ ij_ruby_align_group_field_declarations = true
38
+ ij_ruby_align_multiline_parameters = true
39
+ ij_ruby_blank_lines_around_class = 1
40
+ ij_ruby_blank_lines_around_method = 1
41
+ ij_ruby_chain_calls_alignment = 2
42
+ ij_ruby_convert_brace_block_by_enter = true
43
+ ij_ruby_empty_declarations_style = 1
44
+ ij_ruby_force_newlines_around_visibility_mods = true
45
+ ij_ruby_indent_private_methods = false
46
+ ij_ruby_indent_protected_methods = false
47
+ ij_ruby_indent_public_methods = false
48
+ ij_ruby_indent_visibility_modifiers = true
49
+ ij_ruby_indent_when_cases = false
50
+ ij_ruby_keep_blank_lines_in_code = 1
51
+ ij_ruby_keep_blank_lines_in_declarations = 1
52
+ ij_ruby_keep_line_breaks = true
53
+ ij_ruby_parentheses_around_method_arguments = true
54
+ ij_ruby_spaces_around_assignment_operators = true
55
+ ij_ruby_spaces_around_hashrocket = true
56
+ ij_ruby_spaces_around_other_operators = true
57
+ ij_ruby_spaces_around_pow_operators = true
58
+ ij_ruby_spaces_around_range_operators = false
59
+ ij_ruby_spaces_around_relational_operators = true
60
+ ij_ruby_spaces_within_array_initializer_braces = true
61
+ ij_ruby_spaces_within_braces = true
62
+ ij_ruby_spaces_within_pipes = false
63
+ ij_ruby_use_external_formatter = false
64
+
65
+ [{*.har,*.json}]
66
+ ij_json_array_wrapping = split_into_lines
67
+ ij_json_keep_blank_lines_in_code = 0
68
+ ij_json_keep_indents_on_empty_lines = false
69
+ ij_json_keep_line_breaks = true
70
+ ij_json_keep_trailing_comma = false
71
+ ij_json_object_wrapping = split_into_lines
72
+ ij_json_property_alignment = do_not_align
73
+ ij_json_space_after_colon = true
74
+ ij_json_space_after_comma = true
75
+ ij_json_space_before_colon = false
76
+ ij_json_space_before_comma = false
77
+ ij_json_spaces_within_braces = false
78
+ ij_json_spaces_within_brackets = false
79
+ ij_json_wrap_long_lines = false
80
+
81
+ [{*.markdown,*.md}]
82
+ ij_markdown_force_one_space_after_blockquote_symbol = true
83
+ ij_markdown_force_one_space_after_header_symbol = true
84
+ ij_markdown_force_one_space_after_list_bullet = true
85
+ ij_markdown_force_one_space_between_words = true
86
+ ij_markdown_format_tables = true
87
+ ij_markdown_insert_quote_arrows_on_wrap = true
88
+ ij_markdown_keep_indents_on_empty_lines = false
89
+ ij_markdown_keep_line_breaks_inside_text_blocks = true
90
+ ij_markdown_max_lines_around_block_elements = 1
91
+ ij_markdown_max_lines_around_header = 1
92
+ ij_markdown_max_lines_between_paragraphs = 1
93
+ ij_markdown_min_lines_around_block_elements = 1
94
+ ij_markdown_min_lines_around_header = 1
95
+ ij_markdown_min_lines_between_paragraphs = 1
96
+ ij_markdown_wrap_text_if_long = true
97
+ ij_markdown_wrap_text_inside_blockquotes = true
98
+
99
+ [{*.yaml,*.yml}]
100
+ ij_yaml_align_values_properties = do_not_align
101
+ ij_yaml_autoinsert_sequence_marker = true
102
+ ij_yaml_block_mapping_on_new_line = false
103
+ ij_yaml_indent_sequence_value = true
104
+ ij_yaml_keep_indents_on_empty_lines = false
105
+ ij_yaml_keep_line_breaks = true
106
+ ij_yaml_sequence_on_new_line = false
107
+ ij_yaml_space_before_colon = false
108
+ ij_yaml_spaces_within_braces = true
109
+ ij_yaml_spaces_within_brackets = true
data/exe/sources/rspec ADDED
@@ -0,0 +1 @@
1
+ --require rails_helper
@@ -0,0 +1,5 @@
1
+ inherit_gem:
2
+ rrx_dev: config/rubocop.yml
3
+
4
+ ##
5
+ # Add project specific cops below
@@ -0,0 +1,28 @@
1
+ # Standard rails_helper.rb
2
+ # DO NOT MODIFY
3
+
4
+ require 'spec_helper'
5
+ ENV['RAILS_ENV'] ||= 'test'
6
+ require File.expand_path('../config/environment', __dir__)
7
+ # Prevent database truncation if the environment is production
8
+ abort('The Rails environment is running in production mode!') if Rails.env.production?
9
+ require 'rspec/rails'
10
+
11
+ # Pre-load support files
12
+ require 'rrx_dev/spec'
13
+ Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
14
+
15
+ # Checks for pending migrations and applies them before tests are run.
16
+ # If you are not using ActiveRecord, you can remove these lines.
17
+ begin
18
+ ActiveRecord::Migration.maintain_test_schema!
19
+ rescue ActiveRecord::PendingMigrationError => e
20
+ Rails.logger.debug e.to_s.strip
21
+ exit 1 # rubocop:disable Rails/Exit
22
+ end
23
+
24
+ RSpec.configure do |config|
25
+ config.use_transactional_fixtures = true
26
+ config.infer_spec_type_from_file_location!
27
+ config.filter_rails_from_backtrace!
28
+ end
@@ -0,0 +1,12 @@
1
+ # Standard spec_helper.rb
2
+ # DO NOT MODIFY
3
+
4
+ RSpec.configure do |config|
5
+ config.expect_with :rspec do |expectations|
6
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
7
+ end
8
+
9
+ config.mock_with :rspec do |mocks|
10
+ mocks.verify_partial_doubles = true
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'didja_rails/rswag'
5
+
6
+ swagger do
7
+ # List Swagger documents that will be generates by specs/integration tests
8
+ # NOTE: This MUST be kept in sync with config/initializers/api_docs.rb
9
+
10
+ # Add reusable schemas as additional hash parameters
11
+ #
12
+ # Example
13
+ # doc 'v2/swagger.yaml', 'API v1', 'v1',
14
+ # my_type: object(
15
+ # prop_one: string
16
+ # ),
17
+ # other_type: object(
18
+ # prop_two: integer
19
+ # )
20
+ #
21
+ doc 'v1/swagger.yaml', 'API v1', 'v1'
22
+
23
+ # Add more docs for additional API versions
24
+ #
25
+ # doc 'v2/swagger.yaml', 'API v2', 'v2'
26
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'base'
2
+
3
+ module RrxDev
4
+ class SwaggerGenerator < Base
5
+ def generate!
6
+ copy_new_file 'spec/swagger_helper.rb'
7
+ copy_new_file 'config/initializers/api_docs.rb'
8
+ empty_directory 'spec/integration'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,75 @@
1
+ # Rswag schema helpers
2
+
3
+ def ref(to)
4
+ { '$ref': "#/components/schemas/#{to}" }
5
+ end
6
+
7
+ def object(optional: {}, additional: false, **properties)
8
+ {
9
+ type: :object,
10
+ required: properties.keys.map(&:to_s),
11
+ properties: properties.update(optional),
12
+ additionalProperties: additional
13
+ }.freeze
14
+ end
15
+
16
+ def prop_type(type, description = nil, **options)
17
+ t = { type: }.update(options)
18
+ t[:description] = description if description
19
+ t.freeze
20
+ end
21
+
22
+ def integer(description = nil)
23
+ prop_type :integer, description
24
+ end
25
+
26
+ def string(description = nil, **options)
27
+ prop_type :string, description, **options
28
+ end
29
+
30
+ def date_time(description = nil)
31
+ string description, format: :dateTime
32
+ end
33
+
34
+ def boolean(description = nil)
35
+ prop_type :boolean, description
36
+ end
37
+
38
+ def array(type, description = nil)
39
+ prop_type :array, description, items: type
40
+ end
41
+
42
+ def enum(vals, description = nil)
43
+ string description, enum: vals
44
+ end
45
+
46
+ class SwaggerConfig
47
+ def initialize
48
+ @docs = {}
49
+ end
50
+
51
+ def doc(file, name, version, **schemas)
52
+ @docs[file] = {
53
+ openapi: '3.0.1',
54
+ info: {
55
+ title: name,
56
+ version:
57
+ },
58
+ components: { schemas: }
59
+ }
60
+ end
61
+
62
+ def config
63
+ RSpec.configure do |config|
64
+ config.swagger_root = Rails.root.join('swagger').to_s
65
+ config.swagger_format = :yaml
66
+ config.swagger_docs = @docs
67
+ end
68
+ end
69
+ end
70
+
71
+ def swagger(&block)
72
+ swagger_config = SwaggerConfig.new
73
+ swagger_config.instance_exec(&block)
74
+ swagger_config.config
75
+ end
@@ -0,0 +1,9 @@
1
+ require 'factory_bot_rails'
2
+
3
+ RSpec.configure do |config|
4
+ config.include FactoryBot::Syntax::Methods
5
+ end
6
+
7
+ module Spec
8
+ module FactoryBot; end
9
+ end
@@ -0,0 +1,25 @@
1
+ require 'rspec/parameterized'
2
+
3
+ module Global
4
+ def self.included(other)
5
+ other.let(:json_body) do
6
+ JSON.parse(response.body, object_class: HashWithIndifferentAccess)
7
+ end
8
+
9
+ other.let(:json_response) do
10
+ expect(response).to be_successful
11
+ json_body
12
+ end
13
+
14
+ other.let(:json_error) do
15
+ expect(response).not_to be_successful
16
+ json_body
17
+ end
18
+
19
+ end
20
+ end
21
+
22
+ RSpec.configure do |config|
23
+ config.include ActiveSupport::Testing::Assertions
24
+ config.include Global
25
+ end