factory_bot_instrumentation 0.5.0 → 0.7.1

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: 98a7a69daca8d49bb11b7145e050b3625c5f5638cc961fc3e91377300890c1db
4
- data.tar.gz: ed9d4f5a254eb60cb0241fffbc32a43cfcd6ff2a44ddd476fc299286a37b488b
3
+ metadata.gz: 591ceeab89063ef4a72423185561164932e60b2e7412a4bfa0faa6049988d616
4
+ data.tar.gz: bdabce3cd1a9b292cae4a3d163511debe37379a3909daee6165e6ceba8a7c555
5
5
  SHA512:
6
- metadata.gz: 6df53693fc478ac1ef3895d086efb6b86c7654b16a392fc6c7daa828e36918e1a67706bbc7c00a2f219394b092d9fa8f99bd608c57894e16d81274bb5e5e8bbc
7
- data.tar.gz: d12ec3b074a2b0c1f7a33ea9725d13d28a4095d01e36d68727b057869d9904a3ea9052ad7247221197f2c1d5087e27be29509a71443b34d7edd8da0c7d254267
6
+ metadata.gz: 1ca3413bc194f5fd0036a93041e92b5f0e46aebf2f13cd4e6a938faa866b08d06d8cc20d62c8a6d5154035bd0233f654d9d96769bdda257c193b5a55caacb919
7
+ data.tar.gz: 19eeee8a75a6b7b189ffc650f9e7b604f444eaeb91695122371bbc0995d5cbec5ac7641f845ff98d6b393ed48e0f76eb6e22cbcc76bc0e8939a247139b3c03c9
@@ -0,0 +1,38 @@
1
+ name: Build Documentation
2
+ on:
3
+ repository_dispatch:
4
+ types: [documentation]
5
+
6
+ concurrency:
7
+ group: 'docs'
8
+
9
+ jobs:
10
+ docs:
11
+ name: Build gem documentation
12
+ runs-on: ubuntu-20.04
13
+ timeout-minutes: 5
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+
17
+ - name: Install the correct Ruby version
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: 2.5
21
+ bundler-cache: true
22
+
23
+ - name: Prepare the virtual environment
24
+ uses: hausgold/actions/ci@master
25
+ with:
26
+ clone_token: '${{ secrets.CLONE_TOKEN }}'
27
+ settings: '${{ github.repository }}'
28
+ target: ci/gem-test
29
+
30
+ - name: Build gem documentation
31
+ run: make docs
32
+
33
+ - name: Upload the code coverage report
34
+ run: coverage
35
+
36
+ - name: Add this job to the commit status
37
+ run: commit-status '${{ job.status }}'
38
+ if: always()
@@ -0,0 +1,62 @@
1
+ name: Test
2
+ on:
3
+ push:
4
+ branches:
5
+ - '**'
6
+ schedule:
7
+ - cron: '0 0 * * MON'
8
+
9
+ concurrency:
10
+ group: '${{ github.ref }}'
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ test:
15
+ name: 'Test the gem (Ruby ${{ matrix.ruby }}, Rails ${{ matrix.rails }})'
16
+ runs-on: ubuntu-20.04
17
+ timeout-minutes: 5
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ ruby: [2.4, 2.5, 2.6]
22
+ rails: ['5.0', 5.1, 5.2]
23
+ env:
24
+ BUNDLE_GEMFILE: 'gemfiles/rails_${{ matrix.rails }}.gemfile'
25
+ steps:
26
+ - uses: actions/checkout@v2
27
+
28
+ - name: Install the correct Ruby version
29
+ uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby }}
32
+ bundler-cache: true
33
+
34
+ - name: Prepare the virtual environment
35
+ uses: hausgold/actions/ci@master
36
+ with:
37
+ clone_token: '${{ secrets.CLONE_TOKEN }}'
38
+ settings: '${{ github.repository }}'
39
+ target: ci/gem-test
40
+
41
+ - name: Run the gem tests
42
+ run: make test
43
+
44
+ - name: Upload the code coverage report
45
+ run: coverage
46
+
47
+ trigger-docs:
48
+ name: Trigger the documentation upload
49
+ runs-on: ubuntu-20.04
50
+ timeout-minutes: 2
51
+ needs: test
52
+ if: github.ref == 'refs/heads/master'
53
+ steps:
54
+ - name: Prepare the virtual environment
55
+ uses: hausgold/actions/ci@master
56
+ with:
57
+ clone_token: '${{ secrets.CLONE_TOKEN }}'
58
+ settings: '${{ github.repository }}'
59
+ target: ci/noop
60
+
61
+ - name: Trigger the documentation upload
62
+ run: workflow documentation
data/.rubocop.yml CHANGED
@@ -8,23 +8,21 @@ Documentation:
8
8
 
9
9
  AllCops:
10
10
  DisplayCopNames: true
11
- TargetRubyVersion: 2.4
11
+ TargetRubyVersion: 2.5
12
12
  Exclude:
13
- - db/schema.rb
14
13
  - bin/**/*
15
- - db/migrate/**/*
16
- - vendor/cache/**/*
17
- - vendor/bundle/**/*
14
+ - vendor/**/*
18
15
  - build/**/*
16
+ - gemfiles/**/*
17
+ - spec/dummy/**/*
19
18
 
20
19
  Metrics/BlockLength:
21
20
  Exclude:
22
- # Because of the Grape DSL
23
- - lib/**/*.rb
24
21
  - Rakefile
25
- - hausgold-sdk.gemspec
22
+ - '*.gemspec'
26
23
  - spec/**/*.rb
27
24
  - '**/*.rake'
25
+ - doc/**/*.rb
28
26
 
29
27
  # Document all the things.
30
28
  Style/DocumentationMethod:
@@ -41,3 +39,16 @@ Lint/AmbiguousBlockAssociation:
41
39
  # supported with the +with(hash_including)+ matchers
42
40
  RSpec/MessageSpies:
43
41
  EnforcedStyle: receive
42
+
43
+ # Because nesting makes sense here to group the feature tests
44
+ # more effective. This increases maintainability.
45
+ RSpec/NestedGroups:
46
+ Max: 4
47
+
48
+ # Disable regular Rails spec paths.
49
+ RSpec/FilePath:
50
+ Enabled: false
51
+
52
+ # Because we just implemented the ActiveRecord API.
53
+ Rails/SkipsModelValidations:
54
+ Enabled: false
data/.yardopts ADDED
@@ -0,0 +1,6 @@
1
+ --output-dir=doc/api
2
+ --plugin activesupport-concern
3
+ --markup=rdoc
4
+ -
5
+ README.md
6
+ lib/**/*.rb
data/Appraisals CHANGED
@@ -1,7 +1,4 @@
1
- appraise 'rails-4' do
2
- gem 'rails', '~> 4.2.11'
3
- gem 'rails-api', '~> 0.4.1'
4
- end
1
+ # frozen_string_literal: true
5
2
 
6
3
  appraise 'rails-5.0' do
7
4
  gem 'rails', '~> 5.0.7'
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ### 0.7.1
2
+
3
+ * Migrated to Github Actions
4
+ * Migrated to our own coverage reporting
5
+
6
+ ### 0.7.0
7
+
8
+ * Dropped Rails 4 support
9
+
10
+ ### 0.6.0
11
+
12
+ * Added support for custom error handling and improved the default error
13
+ handling on FactoryBot usage (#9)
14
+
15
+ ### 0.5.1
16
+
17
+ * Corrected a bug on the scenario description update (#8)
18
+
1
19
  ### 0.5.0
2
20
 
3
21
  * Added support for custom before action logics (#7)
data/Makefile CHANGED
@@ -25,6 +25,8 @@ RM ?= rm
25
25
  BUNDLE ?= bundle
26
26
  APPRAISAL ?= appraisal
27
27
  RAKE ?= rake
28
+ RUBOCOP ?= rubocop
29
+ YARD ?= yard
28
30
 
29
31
  # Files
30
32
  GEMFILES ?= $(subst _,-,$(patsubst $(GEMFILES_DIR)/%.gemfile,%,\
@@ -53,6 +55,11 @@ all:
53
55
  # test Run the whole test suite
54
56
  # clean Clean the dependencies
55
57
  #
58
+ # docs Generate the Ruby documentation of the library
59
+ # stats Print the code statistics (library and test suite)
60
+ # notes Print all the notes from the code
61
+ # release Release a new Gem version (maintainers only)
62
+ #
56
63
  # shell Run an interactive shell on the container
57
64
  # shell-irb Run an interactive IRB shell on the container
58
65
 
@@ -62,15 +69,26 @@ install:
62
69
  @$(call run-shell,$(BUNDLE) check || $(BUNDLE) install --path $(VENDOR_DIR))
63
70
  @$(call run-shell,$(BUNDLE) exec $(APPRAISAL) install)
64
71
 
65
- test: install
72
+ test: \
73
+ test-specs \
74
+ test-style
75
+
76
+ test-specs:
66
77
  # Run the whole test suite
67
- @$(call run-shell,$(BUNDLE) exec $(RAKE))
78
+ @$(call run-shell,$(BUNDLE) exec $(RAKE) stats spec)
68
79
 
69
80
  $(TEST_GEMFILES): GEMFILE=$(@:test-%=%)
70
81
  $(TEST_GEMFILES):
71
82
  # Run the whole test suite ($(GEMFILE))
72
83
  @$(call run-shell,$(BUNDLE) exec $(APPRAISAL) $(GEMFILE) $(RAKE))
73
84
 
85
+ test-style: \
86
+ test-style-ruby
87
+
88
+ test-style-ruby:
89
+ # Run the static code analyzer (rubocop)
90
+ @$(call run-shell,$(BUNDLE) exec $(RUBOCOP) -a)
91
+
74
92
  clean:
75
93
  # Clean the dependencies
76
94
  @$(RM) -rf $(VENDOR_DIR)
@@ -83,14 +101,27 @@ endif
83
101
 
84
102
  distclean: clean clean-containers
85
103
 
86
- shell: install
104
+ shell:
87
105
  # Run an interactive shell on the container
88
106
  @$(call run-shell,$(BASH) -i)
89
107
 
90
- shell-irb: install
108
+ shell-irb:
91
109
  # Run an interactive IRB shell on the container
92
110
  @$(call run-shell,bin/console)
93
111
 
112
+ docs:
113
+ # Build the API documentation
114
+ @$(call run-shell,$(BUNDLE) exec $(YARD) -q && \
115
+ $(BUNDLE) exec $(YARD) stats --list-undoc --compact)
116
+
117
+ notes:
118
+ # Print the code statistics (library and test suite)
119
+ @$(call run-shell,$(BUNDLE) exec $(RAKE) notes)
120
+
121
+ stats:
122
+ # Print all the notes from the code
123
+ @$(call run-shell,$(BUNDLE) exec $(RAKE) stats)
124
+
94
125
  release:
95
126
  # Release a new gem version
96
127
  @$(BUNDLE) exec $(RAKE) release
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  ![factory_bot_instrumentation](doc/assets/project.svg)
2
2
 
3
- [![Build Status](https://travis-ci.com/hausgold/factory_bot_instrumentation.svg?token=4XcyqxxmkyBSSV3wWRt7&branch=master)](https://travis-ci.com/hausgold/factory_bot_instrumentation)
3
+ [![Continuous Integration](https://github.com/hausgold/factory_bot_instrumentation/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/hausgold/factory_bot_instrumentation/actions/workflows/test.yml)
4
4
  [![Gem Version](https://badge.fury.io/rb/factory_bot_instrumentation.svg)](https://badge.fury.io/rb/factory_bot_instrumentation)
5
- [![Maintainability](https://api.codeclimate.com/v1/badges/bcf9d9c56e55f4d79747/maintainability)](https://codeclimate.com/repos/5c35e98c8e9b03333000021e/maintainability)
6
- [![Test Coverage](https://api.codeclimate.com/v1/badges/bcf9d9c56e55f4d79747/test_coverage)](https://codeclimate.com/repos/5c35e98c8e9b03333000021e/test_coverage)
7
- [![API docs](https://img.shields.io/badge/docs-API-blue.svg)](https://www.rubydoc.info/gems/factory_bot_instrumentation)
5
+ [![Test Coverage](https://automate-api.hausgold.de/v1/coverage_reports/factory_bot_instrumentation/coverage.svg)](https://knowledge.hausgold.de/coverage)
6
+ [![Test Ratio](https://automate-api.hausgold.de/v1/coverage_reports/factory_bot_instrumentation/ratio.svg)](https://knowledge.hausgold.de/coverage)
7
+ [![API docs](https://automate-api.hausgold.de/v1/coverage_reports/factory_bot_instrumentation/documentation.svg)](https://www.rubydoc.info/gems/factory_bot_instrumentation)
8
8
 
9
9
  This project is dedicated to provide an API and frontend to
10
10
  [factory_bot](https://github.com/thoughtbot/factory_bot) factories to generate
@@ -48,14 +48,6 @@ Add this line to your application's Gemfile:
48
48
  gem 'factory_bot_instrumentation'
49
49
  ```
50
50
 
51
- **Heads up!** In case you use Rails 4.2, you need to add the
52
- [rails-api](https://github.com/rails-api/rails-api) gem as well, because this
53
- feature was first introduced with Rails 5.0.
54
-
55
- ```ruby
56
- gem 'rails-api'
57
- ```
58
-
59
51
  And then execute:
60
52
 
61
53
  ```bash
@@ -316,6 +308,18 @@ FactoryBot::Instrumentation.configure do |conf|
316
308
  controller.render plain: entity.to_json,
317
309
  content_type: 'application/json'
318
310
  end
311
+ # By default we assemble a JSON response on errors which may be
312
+ # helpful for debugging, but you can configure your own logic here
313
+ conf.render_error = proc do |controller, error|
314
+ app_name = FactoryBot::Instrumentation.configuration.application_name
315
+ controller.render status: :internal_server_error,
316
+ content_type: 'application/json',
317
+ plain: {
318
+ application: app_name,
319
+ error: error.message,
320
+ backtrace: error.backtrace.join("\n")
321
+ }.to_json
322
+ end
319
323
  # By default we do not perform any custom +before_action+ filters on the
320
324
  # instrumentation controllers, with this option you can implement your
321
325
  # custom logic like authentication
data/Rakefile CHANGED
@@ -7,20 +7,86 @@ ENV['DISABLE_DATABASE_ENVIRONMENT_CHECK'] = '1'
7
7
  require 'bundler/setup'
8
8
  require 'bundler/gem_tasks'
9
9
  require 'rspec/core/rake_task'
10
+ require 'rails/code_statistics'
11
+ require 'pp'
10
12
 
11
- APP_RAKEFILE = File.expand_path('../spec/dummy/Rakefile', __FILE__)
13
+ APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
12
14
  load 'rails/tasks/engine.rake'
13
15
 
14
16
  Bundler::GemHelper.install_tasks
15
17
 
16
- Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
18
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each { |f| load f }
17
19
 
18
20
  require 'rspec/core'
19
21
  require 'rspec/core/rake_task'
20
22
 
21
23
  desc 'Run all specs in spec directory (excluding plugin specs)'
22
24
  RSpec::Core::RakeTask.new(spec: [
23
- 'db:drop', 'db:create', 'db:migrate', 'db:setup'
24
- ])
25
+ 'db:drop', 'db:create', 'db:migrate', 'db:setup'
26
+ ])
25
27
 
26
28
  task default: :spec
29
+
30
+ # Load some railties tasks
31
+ load 'rails/tasks/statistics.rake'
32
+ load 'rails/tasks/annotations.rake'
33
+
34
+ # Clear the default statistics directory constant
35
+ #
36
+ # rubocop:disable Style/MutableConstant because we define it
37
+ Object.send(:remove_const, :STATS_DIRECTORIES)
38
+ ::STATS_DIRECTORIES = []
39
+ # rubocop:enable Style/MutableConstant
40
+
41
+ # Monkey patch the Rails +CodeStatistics+ class to support configurable
42
+ # patterns per path. This is reuqired to support top-level only file matches.
43
+ class CodeStatistics
44
+ DEFAULT_PATTERN = /^(?!\.).*?\.(rb|js|coffee|rake)$/.freeze
45
+
46
+ # Pass the possible +pattern+ argument down to the
47
+ # +calculate_directory_statistics+ method call.
48
+ def calculate_statistics
49
+ Hash[@pairs.map do |pair|
50
+ [pair.first, calculate_directory_statistics(*pair[1..-1])]
51
+ end]
52
+ end
53
+
54
+ # Match the pattern against the individual file name and the relative file
55
+ # path. This allows top-level only matches.
56
+ def calculate_directory_statistics(directory, pattern = DEFAULT_PATTERN)
57
+ stats = CodeStatisticsCalculator.new
58
+
59
+ Dir.foreach(directory) do |file_name|
60
+ path = "#{directory}/#{file_name}"
61
+
62
+ if File.directory?(path) && (/^\./ !~ file_name)
63
+ stats.add(calculate_directory_statistics(path, pattern))
64
+ elsif file_name =~ pattern || path =~ pattern
65
+ stats.add_by_file_path(path)
66
+ end
67
+ end
68
+
69
+ stats
70
+ end
71
+ end
72
+
73
+ # Configure all code statistics directories
74
+ vendors = [
75
+ [:unshift, 'Top-levels', 'lib'],
76
+ [:unshift, 'Top-levels specs', 'spec', %r{spec/[^/]+_spec\.rb$}],
77
+ [:unshift, 'Javascript', 'app/assets'],
78
+ [:unshift, 'Controllers', 'app/controllers'],
79
+ [:unshift, 'Controllers specs', 'spec/controllers']
80
+ ].reverse
81
+
82
+ vendors.each do |method, type, dir, pattern|
83
+ ::STATS_DIRECTORIES.send(method, [type, dir, pattern].compact)
84
+ ::CodeStatistics::TEST_TYPES << type if type.include? 'specs'
85
+ end
86
+
87
+ # Setup annotations
88
+ ENV['SOURCE_ANNOTATION_DIRECTORIES'] = 'spec,doc'
89
+ desc 'Enumerate all annotations'
90
+ task :notes do
91
+ SourceAnnotationExtractor.enumerate '@?OPTIMIZE|@?FIXME|@?TODO', tag: true
92
+ end
@@ -101,7 +101,7 @@ CreateForm.prototype.bind = function()
101
101
  this.submit();
102
102
  });
103
103
 
104
- this.select.on('change', this.updateDesc);
104
+ this.select.on('change', this.updateDesc.bind(this));
105
105
  this.updateDesc();
106
106
  };
107
107
 
@@ -1,34 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module FactoryBot::Instrumentation
4
- # A base engine application controller.
5
- class ApplicationController < ActionController::API
6
- # Extend our core functionality to support easy authentication logics
7
- include ActionController::HttpAuthentication::Basic::ControllerMethods
8
- include ActionController::HttpAuthentication::Digest::ControllerMethods
9
- include ActionController::HttpAuthentication::Token::ControllerMethods
3
+ module FactoryBot
4
+ module Instrumentation
5
+ # A base engine application controller.
6
+ class ApplicationController < ActionController::API
7
+ # Extend our core functionality to support easy authentication logics
8
+ include ActionController::HttpAuthentication::Basic::ControllerMethods
9
+ include ActionController::HttpAuthentication::Digest::ControllerMethods
10
+ include ActionController::HttpAuthentication::Token::ControllerMethods
10
11
 
11
- # Allow the users to implement additional instrumentation-wide before
12
- # action logic, like authentication
13
- before_action do |controller|
14
- if FactoryBot::Instrumentation.configuration.before_action
15
- instance_eval &FactoryBot::Instrumentation.configuration.before_action
12
+ # Allow the users to implement additional instrumentation-wide before
13
+ # action logic, like authentication
14
+ before_action do |_controller|
15
+ if FactoryBot::Instrumentation.configuration.before_action
16
+ instance_eval(
17
+ &FactoryBot::Instrumentation.configuration.before_action
18
+ )
19
+ end
16
20
  end
17
- end
18
21
 
19
- protected
22
+ protected
20
23
 
21
- # A simple shortcut for Basic Auth on Rails 4.2+. Just configure the
22
- # username and password and you're ready to check the current request.
23
- #
24
- # @param username [String] the required user name
25
- # @param password [String] the required password of the user
26
- # @param realm [String] the authentication realm
27
- def basic_auth(username:, password:, realm: 'Instrumentation')
28
- authenticate_or_request_with_http_basic(realm) \
29
- do |given_name, given_password|
30
- ActiveSupport::SecurityUtils.secure_compare(given_name, username) &
31
- ActiveSupport::SecurityUtils.secure_compare(given_password, password)
24
+ # A simple shortcut for Basic Auth on Rails 4.2+. Just configure the
25
+ # username and password and you're ready to check the current request.
26
+ #
27
+ # @param username [String] the required user name
28
+ # @param password [String] the required password of the user
29
+ # @param realm [String] the authentication realm
30
+ def basic_auth(username:, password:, realm: 'Instrumentation')
31
+ authenticate_or_request_with_http_basic(realm) \
32
+ do |given_name, given_password|
33
+ ActiveSupport::SecurityUtils.secure_compare(given_name, username) &
34
+ ActiveSupport::SecurityUtils.secure_compare(
35
+ given_password, password
36
+ )
37
+ end
32
38
  end
33
39
  end
34
40
  end
@@ -1,119 +1,131 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module FactoryBot::Instrumentation
4
- # The Instrumentation engine controller with frontend and API actions.
5
- class RootController < ApplicationController
6
- # This is required to make API controllers template renderable
7
- include ActionView::Layouts
3
+ module FactoryBot
4
+ module Instrumentation
5
+ # The Instrumentation engine controller with frontend and API actions.
6
+ class RootController < ApplicationController
7
+ # This is required to make API controllers template renderable
8
+ include ActionView::Layouts
8
9
 
9
- # Configure the default application layout
10
- layout 'factory_bot/instrumentation/application'
10
+ # Configure the default application layout
11
+ layout 'factory_bot/instrumentation/application'
11
12
 
12
- # Show the instrumentation frontend which features the output of configured
13
- # dynamic seeds scenarios. The frontend allows humans to generate new seed
14
- # data on the fly.
15
- def index
16
- @instrumentation = instrumentation
17
- @scenarios = scenarios
18
- @config = FactoryBot::Instrumentation.configuration
19
- render :index, layout: true
20
- end
13
+ # Show the instrumentation frontend which features the output of
14
+ # configured dynamic seeds scenarios. The frontend allows humans to
15
+ # generate new seed data on the fly.
16
+ def index
17
+ @instrumentation = instrumentation
18
+ @scenarios = scenarios
19
+ @config = FactoryBot::Instrumentation.configuration
20
+ render :index, layout: true
21
+ end
21
22
 
22
- # Create a new entity with the given factory settings to create on demand
23
- # dependencies for your testing needs. You can pass in requests without
24
- # authentication in the following JSON format:
25
- #
26
- # {
27
- # "factory": "user",
28
- # "traits": ["confirmed"],
29
- # "overwrite": {
30
- # "first_name": "Bernd",
31
- # "last_name": "Müller",
32
- # "email": "bernd.mueller@example.com",
33
- # "password": "secret"
34
- # }
35
- # }
36
- #
37
- # The result is the API v1 representation of the created entity.
38
- def create
39
- # Reload the factories to improve the test development experience
40
- FactoryBot.reload
41
- # Call the factory construction with the user given parameters
42
- entity = FactoryBot.create(*factory_params)
43
- # Render the resulting entity with the configured rendering block
44
- FactoryBot::Instrumentation.configuration.render_entity.call(self, entity)
45
- rescue StandardError => err
46
- # Log for local factory debugging and re-raise for canary onwards
47
- Rails.logger.error("#{err}\n#{err.backtrace.join("\n")}")
48
- raise err
49
- end
23
+ # Create a new entity with the given factory settings to create on demand
24
+ # dependencies for your testing needs. You can pass in requests without
25
+ # authentication in the following JSON format:
26
+ #
27
+ # {
28
+ # "factory": "user",
29
+ # "traits": ["confirmed"],
30
+ # "overwrite": {
31
+ # "first_name": "Bernd",
32
+ # "last_name": "Schulze",
33
+ # "email": "bernd.schulze@example.com",
34
+ # "password": "secret"
35
+ # }
36
+ # }
37
+ #
38
+ # The result is the API v1 representation of the created entity.
39
+ def create
40
+ # Reload the factories to improve the test development experience
41
+ FactoryBot.reload
42
+ # Call the factory construction with the user given parameters
43
+ entity = FactoryBot.create(*factory_params)
44
+ # Render the resulting entity with the configured rendering block
45
+ FactoryBot::Instrumentation.configuration.render_entity.call(
46
+ self, entity
47
+ )
48
+ rescue StandardError => err
49
+ # Handle any error gracefully with the configured error handler
50
+ FactoryBot::Instrumentation.configuration.render_error.call(self, err)
51
+ end
50
52
 
51
- private
53
+ private
52
54
 
53
- # Parse the given parameters from the request and build
54
- # a valid FactoryBot options set.
55
- #
56
- # @return [Array<Mixed>] the FactoryBot options
57
- def factory_params
58
- data = params.permit(:factory, traits: [])
55
+ # Parse the given parameters from the request and build
56
+ # a valid FactoryBot options set.
57
+ #
58
+ # @return [Array<Mixed>] the FactoryBot options
59
+ #
60
+ # rubocop:disable Metrics/MethodLength because of the Rails
61
+ # version handling
62
+ def factory_params
63
+ data = params.permit(:factory, traits: [])
59
64
 
60
- if Rails::VERSION::MAJOR >= 5
61
- overwrite = params.to_unsafe_h.fetch(:overwrite, {})
62
- .deep_symbolize_keys
63
- else
64
- overwrite = params.fetch('overwrite', {}).deep_symbolize_keys
65
- end
65
+ overwrite = if Rails::VERSION::MAJOR >= 5
66
+ params.to_unsafe_h.fetch(:overwrite, {})
67
+ .deep_symbolize_keys
68
+ else
69
+ params.fetch('overwrite', {}).deep_symbolize_keys
70
+ end
66
71
 
67
- [
68
- data.fetch(:factory).to_sym,
69
- *data.fetch(:traits, []).map(&:to_sym),
70
- **overwrite
71
- ]
72
- end
72
+ [
73
+ data.fetch(:factory).to_sym,
74
+ *data.fetch(:traits, []).map(&:to_sym),
75
+ **overwrite
76
+ ]
77
+ end
78
+ # rubocop:enable Metrics/MethodLength
73
79
 
74
- # Unfortunately +Rails.configuration.instrumentation+ is only read once and
75
- # do not hot-reload on changes. Thats why we read this file manually to get
76
- # always a fresh state.
77
- #
78
- # @return [Hash{String => Mixed}] the instrumentation scenarios
79
- def instrumentation
80
- config_file = FactoryBot::Instrumentation.configuration.config_file.to_s
81
- content = Pathname.new(config_file).read
82
- template = ERB.new(content)
83
- YAML.load(template.result(binding))[Rails.env]
84
- end
80
+ # Unfortunately +Rails.configuration.instrumentation+ is only read once
81
+ # and do not hot-reload on changes. Thats why we read this file manually
82
+ # to get always a fresh state.
83
+ #
84
+ # @return [Hash{String => Mixed}] the instrumentation scenarios
85
+ #
86
+ # rubocop:disable Security/YAMLLoad because we just load
87
+ # local configuration files here
88
+ def instrumentation
89
+ config_file = FactoryBot::Instrumentation.configuration.config_file.to_s
90
+ content = Pathname.new(config_file).read
91
+ template = ERB.new(content)
92
+ YAML.load(template.result(binding))[Rails.env]
93
+ end
94
+ # rubocop:enable Security/YAMLLoad
85
95
 
86
- # Map all the instrumentation scenarios into groups and pass them back.
87
- #
88
- # @return [Hash{String => Array}] the grouped scenarios
89
- def scenarios
90
- instrumentation['scenarios'].each_with_object({}) do |scenario, memo|
91
- group = scenario_group(scenario['name'])
92
- scenario['group'] = group
93
- memo[group] = [] unless memo.key? group
94
- memo[group] << scenario
96
+ # Map all the instrumentation scenarios into groups and pass them back.
97
+ #
98
+ # @return [Hash{String => Array}] the grouped scenarios
99
+ def scenarios
100
+ instrumentation['scenarios'].each_with_object({}) do |scenario, memo|
101
+ group = scenario_group(scenario['name'])
102
+ scenario['group'] = group
103
+ memo[group] = [] unless memo.key? group
104
+ memo[group] << scenario
105
+ end
95
106
  end
96
- end
97
107
 
98
- # Map all the configured scenario groups to a useable hash.
99
- #
100
- # @return [Hash{Regexp => String}] the group mapping
101
- def groups
102
- instrumentation['groups'].each_with_object({}) do |(key, val), memo|
103
- memo[Regexp.new(Regexp.quote(key))] = val
108
+ # Map all the configured scenario groups to a useable hash.
109
+ #
110
+ # @return [Hash{Regexp => String}] the group mapping
111
+ def groups
112
+ instrumentation['groups'].each_with_object({}) do |(key, val), memo|
113
+ memo[Regexp.new(Regexp.quote(key))] = val
114
+ end
104
115
  end
105
- end
106
116
 
107
- # Fetch the group name for a given scenario name. This will utilize the
108
- # +SCENARIO_GROUPS+ map.
109
- #
110
- # @param name [String] the scenario name
111
- # @return [String] the group name
112
- def scenario_group(name)
113
- groups.map do |pattern, group_name|
114
- next unless pattern.match? name
115
- group_name
116
- end.compact.first || 'Various'
117
+ # Fetch the group name for a given scenario name. This will utilize the
118
+ # +SCENARIO_GROUPS+ map.
119
+ #
120
+ # @param name [String] the scenario name
121
+ # @return [String] the group name
122
+ def scenario_group(name)
123
+ groups.map do |pattern, group_name|
124
+ next unless pattern.match? name
125
+
126
+ group_name
127
+ end.compact.first || 'Various'
128
+ end
117
129
  end
118
130
  end
119
131
  end
@@ -21,13 +21,18 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ['lib']
23
23
 
24
- spec.add_runtime_dependency 'rails', '>= 4.0'
25
24
  spec.add_runtime_dependency 'factory_bot'
25
+ spec.add_runtime_dependency 'rails', '>= 5.0'
26
26
 
27
+ spec.add_development_dependency 'appraisal'
27
28
  spec.add_development_dependency 'bundler', '>= 1.16', '< 3'
29
+ spec.add_development_dependency 'railties', '>= 4.2.0', '< 6.1'
28
30
  spec.add_development_dependency 'rspec-rails', '~> 3.8'
29
- spec.add_development_dependency 'simplecov', '~> 0.15'
30
- spec.add_development_dependency 'timecop', '~> 0.9.1'
31
+ spec.add_development_dependency 'rubocop', '~> 0.63.1'
32
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.31'
33
+ spec.add_development_dependency 'simplecov', '< 0.18'
31
34
  spec.add_development_dependency 'sqlite3', '~> 1.3.6'
32
- spec.add_development_dependency 'appraisal'
35
+ spec.add_development_dependency 'timecop', '~> 0.9.1'
36
+ spec.add_development_dependency 'yard', '~> 0.9.18'
37
+ spec.add_development_dependency 'yard-activesupport-concern', '~> 0.0.1'
33
38
  end
@@ -25,6 +25,21 @@ module FactoryBot
25
25
  end
26
26
  end
27
27
 
28
+ # By default we assemble a JSON response on errors which may be
29
+ # helpful for debugging, but you can configure your own logic here
30
+ config_accessor(:render_error) do
31
+ proc do |controller, error|
32
+ app_name = FactoryBot::Instrumentation.configuration.application_name
33
+ controller.render status: :internal_server_error,
34
+ content_type: 'application/json',
35
+ plain: {
36
+ application: app_name,
37
+ error: error.message,
38
+ backtrace: error.backtrace.join("\n")
39
+ }.to_json
40
+ end
41
+ end
42
+
28
43
  # By default we do not perform any custom +before_action+ filters on the
29
44
  # instrumentation controllers, with this option you can implement your
30
45
  # custom logic like authentication
@@ -2,6 +2,6 @@
2
2
 
3
3
  module FactoryBot
4
4
  module Instrumentation
5
- VERSION = '0.5.0'.freeze
5
+ VERSION = '0.7.1'
6
6
  end
7
7
  end
@@ -13,6 +13,7 @@ require 'factory_bot/instrumentation/configuration'
13
13
  require 'factory_bot/instrumentation/engine'
14
14
 
15
15
  module FactoryBot
16
+ # The top level namespace for the factory_bot_instrumentation gem.
16
17
  module Instrumentation
17
18
  class << self
18
19
  attr_writer :configuration
metadata CHANGED
@@ -1,37 +1,51 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factory_bot_instrumentation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hermann Mayer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-20 00:00:00.000000000 Z
11
+ date: 2021-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: factory_bot
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rails
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
18
32
  - !ruby/object:Gem::Version
19
- version: '4.0'
33
+ version: '5.0'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - ">="
25
39
  - !ruby/object:Gem::Version
26
- version: '4.0'
40
+ version: '5.0'
27
41
  - !ruby/object:Gem::Dependency
28
- name: factory_bot
42
+ name: appraisal
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
32
46
  - !ruby/object:Gem::Version
33
47
  version: '0'
34
- type: :runtime
48
+ type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
@@ -58,6 +72,26 @@ dependencies:
58
72
  - - "<"
59
73
  - !ruby/object:Gem::Version
60
74
  version: '3'
75
+ - !ruby/object:Gem::Dependency
76
+ name: railties
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 4.2.0
82
+ - - "<"
83
+ - !ruby/object:Gem::Version
84
+ version: '6.1'
85
+ type: :development
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: 4.2.0
92
+ - - "<"
93
+ - !ruby/object:Gem::Version
94
+ version: '6.1'
61
95
  - !ruby/object:Gem::Dependency
62
96
  name: rspec-rails
63
97
  requirement: !ruby/object:Gem::Requirement
@@ -72,20 +106,62 @@ dependencies:
72
106
  - - "~>"
73
107
  - !ruby/object:Gem::Version
74
108
  version: '3.8'
109
+ - !ruby/object:Gem::Dependency
110
+ name: rubocop
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: 0.63.1
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: 0.63.1
123
+ - !ruby/object:Gem::Dependency
124
+ name: rubocop-rspec
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '1.31'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '1.31'
75
137
  - !ruby/object:Gem::Dependency
76
138
  name: simplecov
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "<"
142
+ - !ruby/object:Gem::Version
143
+ version: '0.18'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "<"
149
+ - !ruby/object:Gem::Version
150
+ version: '0.18'
151
+ - !ruby/object:Gem::Dependency
152
+ name: sqlite3
77
153
  requirement: !ruby/object:Gem::Requirement
78
154
  requirements:
79
155
  - - "~>"
80
156
  - !ruby/object:Gem::Version
81
- version: '0.15'
157
+ version: 1.3.6
82
158
  type: :development
83
159
  prerelease: false
84
160
  version_requirements: !ruby/object:Gem::Requirement
85
161
  requirements:
86
162
  - - "~>"
87
163
  - !ruby/object:Gem::Version
88
- version: '0.15'
164
+ version: 1.3.6
89
165
  - !ruby/object:Gem::Dependency
90
166
  name: timecop
91
167
  requirement: !ruby/object:Gem::Requirement
@@ -101,33 +177,33 @@ dependencies:
101
177
  - !ruby/object:Gem::Version
102
178
  version: 0.9.1
103
179
  - !ruby/object:Gem::Dependency
104
- name: sqlite3
180
+ name: yard
105
181
  requirement: !ruby/object:Gem::Requirement
106
182
  requirements:
107
183
  - - "~>"
108
184
  - !ruby/object:Gem::Version
109
- version: 1.3.6
185
+ version: 0.9.18
110
186
  type: :development
111
187
  prerelease: false
112
188
  version_requirements: !ruby/object:Gem::Requirement
113
189
  requirements:
114
190
  - - "~>"
115
191
  - !ruby/object:Gem::Version
116
- version: 1.3.6
192
+ version: 0.9.18
117
193
  - !ruby/object:Gem::Dependency
118
- name: appraisal
194
+ name: yard-activesupport-concern
119
195
  requirement: !ruby/object:Gem::Requirement
120
196
  requirements:
121
- - - ">="
197
+ - - "~>"
122
198
  - !ruby/object:Gem::Version
123
- version: '0'
199
+ version: 0.0.1
124
200
  type: :development
125
201
  prerelease: false
126
202
  version_requirements: !ruby/object:Gem::Requirement
127
203
  requirements:
128
- - - ">="
204
+ - - "~>"
129
205
  - !ruby/object:Gem::Version
130
- version: '0'
206
+ version: 0.0.1
131
207
  description: Allow your testers to generate test data on demand
132
208
  email:
133
209
  - hermann.mayer92@gmail.com
@@ -136,11 +212,13 @@ extensions: []
136
212
  extra_rdoc_files: []
137
213
  files:
138
214
  - ".editorconfig"
215
+ - ".github/workflows/documentation.yml"
216
+ - ".github/workflows/test.yml"
139
217
  - ".gitignore"
140
218
  - ".rspec"
141
219
  - ".rubocop.yml"
142
220
  - ".simplecov"
143
- - ".travis.yml"
221
+ - ".yardopts"
144
222
  - Appraisals
145
223
  - CHANGELOG.md
146
224
  - Gemfile
@@ -177,7 +255,6 @@ files:
177
255
  - doc/assets/regular.png
178
256
  - docker-compose.yml
179
257
  - factory_bot_instrumentation.gemspec
180
- - gemfiles/rails_4.gemfile
181
258
  - gemfiles/rails_5.0.gemfile
182
259
  - gemfiles/rails_5.1.gemfile
183
260
  - gemfiles/rails_5.2.gemfile
@@ -188,7 +265,7 @@ files:
188
265
  homepage: https://github.com/hausgold/factory_bot_instrumentation
189
266
  licenses: []
190
267
  metadata: {}
191
- post_install_message:
268
+ post_install_message:
192
269
  rdoc_options: []
193
270
  require_paths:
194
271
  - lib
@@ -203,8 +280,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
280
  - !ruby/object:Gem::Version
204
281
  version: '0'
205
282
  requirements: []
206
- rubygems_version: 3.1.2
207
- signing_key:
283
+ rubygems_version: 3.2.16
284
+ signing_key:
208
285
  specification_version: 4
209
286
  summary: Allow your testers to generate test data on demand
210
287
  test_files: []
data/.travis.yml DELETED
@@ -1,31 +0,0 @@
1
- env:
2
- global:
3
- - CC_TEST_REPORTER_ID=fb31117c43f12bf12f2d5a2b8ab4b3fe1b18aa874490f7f3db5502aa9ddb65fc
4
-
5
- sudo: false
6
- language: ruby
7
- cache: bundler
8
- rvm:
9
- - 2.6
10
- - 2.5
11
- - 2.4
12
-
13
- gemfile:
14
- - gemfiles/rails_4.gemfile
15
- - gemfiles/rails_5.0.gemfile
16
- - gemfiles/rails_5.1.gemfile
17
- - gemfiles/rails_5.2.gemfile
18
-
19
- before_install: |
20
- [[ ! "${BUNDLE_GEMFILE}" =~ rails_4 ]] \
21
- && (gem install bundler) \
22
- || (yes n | rvm @global do gem uninstall bundler; \
23
- gem install bundler -v '~> 1.0') \
24
-
25
- before_script:
26
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
27
- - chmod +x ./cc-test-reporter
28
- - ./cc-test-reporter before-build
29
- script: bundle exec rake
30
- after_script:
31
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "rails", "~> 4.2.11"
6
- gem "rails-api", "~> 0.4.1"
7
-
8
- gemspec path: "../"