Skip to content

Commit

Permalink
Add script to check monkey patches
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyshields committed Sep 3, 2023
1 parent 30f46d4 commit 895854c
Show file tree
Hide file tree
Showing 2 changed files with 248 additions and 0 deletions.
22 changes: 22 additions & 0 deletions .github/workflows/monkey.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: Check Monkey Patches

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
env:
CI: true
TESTOPTS: "-v"
steps:
- uses: actions/checkout@v3
- name: Set up Ruby 3.0
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.0
bundler-cache: true
- name: bundle
run: bundle install --jobs 4 --retry 3
- name: Run RSpec Monkey Patch check
run: bundle exec rspec spec/check_monkey_patches.rb
226 changes: 226 additions & 0 deletions spec/check_monkey_patches.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# frozen_string_literal: true

raise 'Monkey patches spec must be run before loading Mongoid' if defined?(Mongoid::Document)

require 'rspec'

# Require dependency gems that add monkey patches
require 'active_support/all'
require 'bson'
require 'openssl'
require 'ruby2_keywords'

CLASSES = [
Object,
Array,
BigDecimal,
Date,
DateTime,
FalseClass,
Float,
Hash,
Integer,
Module,
NilClass,
Range,
Regexp,
Set,
String,
Symbol,
Time,
TrueClass,
ActiveSupport::TimeWithZone,
BSON::Binary,
BSON::Decimal128,
BSON::ObjectId,
BSON::Regexp,
BSON::Regexp::Raw
].freeze

instance_methods = CLASSES.index_with(&:instance_methods)
class_methods = CLASSES.index_with(&:methods)

require 'mongoid'

ADDED_INSTANCE_METHODS = instance_methods.each_with_object({}) do |(klass, methods), hash|
hash[klass] = klass.instance_methods.sort - methods - (hash[Object] || [])
end

ADDED_CLASS_METHODS = class_methods.each_with_object({}) do |(klass, methods), hash|
hash[klass] = klass.methods.sort - methods - (hash[Object] || []) - ADDED_INSTANCE_METHODS[Object]
end

EXPECTED_INSTANCE_METHODS = {
Object => %i[
__add__
__add_from_array__
__array__
__deep_copy__
__evolve_object_id__
__expand_complex__
__find_args__
__intersect__
__intersect_from_array__
__intersect_from_object__
__mongoize_object_id__
__mongoize_time__
__setter__
__sortable__
__to_inc__
__union__
__union_from_object__
blank_criteria
blank_criteria?
do_or_do_not
ivar
mongoize
multi_arged?
numeric?
regexp?
remove_ivar
resizable?
substitutable
you_must
].freeze,
Array => %i[
__evolve_date__
__evolve_time__
__sort_option__
__sort_pair__
delete_one
].freeze,
Date => %i[
__evolve_date__
__evolve_time__
].freeze,
DateTime => %i[
__evolve_date__
__evolve_time__
].freeze,
Float => %i[
__evolve_date__
__evolve_time__
].freeze,
Hash => %i[
__consolidate__
__sort_option__
_mongoid_unsatisfiable_criteria?
delete_id
extract_id
to_criteria
].freeze,
Integer => %i[
__evolve_date__
__evolve_time__
unconvertable_to_bson?
].freeze,
Module => %i[
re_define_method
].freeze,
NilClass => %i[
__evolve_date__
__evolve_time__
__expanded__
__override__
collectionize
].freeze,
Range => %i[
__evolve_date__
__evolve_range__
__evolve_time__
].freeze,
String => %i[
__evolve_date__
__evolve_time__
__expr_part__
__mongo_expression__
__sort_option__
collectionize
mongoid_id?
unconvertable_to_bson
unconvertable_to_bson=
unconvertable_to_bson?
].freeze,
Symbol => %i[
__expr_part__
add_to_set
all
asc
ascending
avg
desc
descending
elem_match
eq
exists
first
gt
gte
in
intersects_line
intersects_point
intersects_polygon
last
lt
lte
max
min
mod
mongoid_id?
ne
near
near_sphere
nin
not
push
sum
with_size
with_type
within_box
within_polygon
].freeze,
Time => %i[
__evolve_date__
__evolve_time__
].freeze,
ActiveSupport::TimeWithZone => %i[
__evolve_date__
__evolve_time__
_bson_to_i
bson_type
to_bson
].freeze,
BSON::Decimal128 => %i[
__evolve_decimal128__
].freeze
}.freeze

EXPECTED_CLASS_METHODS = {
Object => %i[
__mongoize_fk__
demongoize
evolve
re_define_method
].freeze,
Float => %i[__numeric__].freeze,
Integer => %i[__numeric__].freeze,
String => %i[__expr_part__].freeze,
Symbol => %i[add_key].freeze,
Time => %i[configured].freeze
}.freeze

RSpec.describe('Monkey patches') do

CLASSES.each do |klass|

context klass.name do
it 'adds no unexpected instance methods' do
expect(ADDED_INSTANCE_METHODS[klass]).to eq(EXPECTED_INSTANCE_METHODS[klass]&.sort || [])
end

it 'adds no unexpected class methods' do
expect(ADDED_CLASS_METHODS[klass]).to eq(EXPECTED_CLASS_METHODS[klass]&.sort || [])
end
end
end
end

0 comments on commit 895854c

Please sign in to comment.