suggest_rb 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b4767a25d85dccc93708b86da3fc1abaf21163f1
4
+ data.tar.gz: 9dac49839363b1aa5cea4c1905797d41a7d9ecf1
5
+ SHA512:
6
+ metadata.gz: 01fe386299c1c54e02833812316aa96097243eeef9460474bdbd28b8d4e1535d4db8ae961db7be8baa98a31ba649b6ddd04ebaf2e85e6dfbc04eae758ad1984f
7
+ data.tar.gz: 143bd64a2fee717bfdf443fa1f788014141112aef692ca7e9c5bf7befe64ccce04bab339c22cbdb19cd6f7a6e1c980bc0134f1aaa3191ff699d7d74ce982eefa
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.lock
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.3.8
7
+ before_install: gem install bundler -v 1.17.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in suggest.gemspec
6
+ gemspec
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Suggest
2
+
3
+ tells you which method does the thing you want to do
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ gem install suggest_rb
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```rb
14
+ require 'suggest'
15
+
16
+ # Object#what_returns? tells you which method returns the value
17
+ [1,2,3].what_returns? 1
18
+ => [:first, :min]
19
+
20
+ # You can also specify the args you want that method to take
21
+ [1,2,3].what_returns? [1], args: [1]
22
+ => [:sample, :first, :take, :grep, :min]
23
+
24
+ # By default, it only returns methods that don't mutate the object
25
+ [1,2,3].what_returns? [1], args: [1], allow_mutation: true
26
+ => [:sample, :first, :take, :shift, :grep, :min]
27
+
28
+ # It works on several core modules including String
29
+ "HELLO".what_returns? "hello"
30
+ => [:downcase, :swapcase]
31
+
32
+ # You can also specify a block that you want the method to accept
33
+ [1,2,3,4].what_returns?({true => [2,4], false => [1,3]}) { |n| n % 2 == 0 }
34
+ => [:group_by]
35
+
36
+ # Object#what_mutates? tells you which method changes the object to the desired state
37
+ [1,2,3].what_mutates? [2, 3]
38
+ => [:shift]
39
+
40
+ # You can also match on the return value
41
+ [1,2,3].what_mutates? [2, 3], returns: 1
42
+ => [:shift]
43
+
44
+ [1,2,3].what_mutates? [2, 3], returns: 2
45
+ => []
46
+
47
+ # You can specify which args to pass to the method
48
+ [1,2,3].what_mutates? [3], args: [2]
49
+ => [:shift]
50
+
51
+ # It also works on a bunch of core modules
52
+ "HELLO".what_mutates? "hello"
53
+ => [:swapcase!, :downcase!]
54
+
55
+ # And you can give it a block as well
56
+ [1,2,3,4].what_mutates? [2,4] { |n| n % 2 == 0 }
57
+ => [:select!, :keep_if]
58
+ ```
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "suggest"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,3 @@
1
+ module Suggest
2
+ VERSION = "0.1.0"
3
+ end
data/lib/suggest.rb ADDED
@@ -0,0 +1,64 @@
1
+ require "suggest/version"
2
+ require "set"
3
+
4
+ module Suggest
5
+ SUGGEST_MODS = Set.new([Array, Enumerable, String, Hash, Regexp, Integer])
6
+ UNSAFE = Set.new([Array.instance_method(:cycle)])
7
+
8
+ module Mixin
9
+ def what_returns?(expected, args: [], allow_mutation: false)
10
+ block = Proc.new if block_given?
11
+
12
+ applicable_methods = self.methods.map(&method(:method)).select { |m| SUGGEST_MODS.include?(m.owner) }
13
+
14
+ applicable_methods.select do |m|
15
+ arity = m.arity
16
+ next unless arity == -1 || arity == args.count
17
+
18
+ post = clone
19
+ if block
20
+ next if UNSAFE.include?(m.unbind)
21
+ result = post.public_send(m.name, *args, &block) rescue next
22
+ else
23
+ result = post.public_send(m.name, *args) rescue next
24
+ end
25
+
26
+ next unless allow_mutation || self == post
27
+
28
+ Suggest.eq?(result, expected)
29
+ end.map(&:name)
30
+ end
31
+
32
+ def what_mutates?(expected, opts = {})
33
+ args = opts[:args] || []
34
+ block = Proc.new if block_given?
35
+
36
+ applicable_methods = self.methods.map(&method(:method)).select { |m| SUGGEST_MODS.include?(m.owner) }
37
+
38
+ applicable_methods.select do |m|
39
+ arity = m.arity
40
+ next unless arity == -1 || arity == args.count
41
+
42
+ post = clone
43
+ if block
44
+ next if UNSAFE.include?(m.unbind)
45
+ result = post.public_send(m.name, *args, &block) rescue next
46
+ else
47
+ result = post.public_send(m.name, *args) rescue next
48
+ end
49
+
50
+ if opts.key?(:returns)
51
+ next unless Suggest.eq?(result, opts[:returns])
52
+ end
53
+
54
+ Suggest.eq?(post, expected)
55
+ end.map(&:name)
56
+ end
57
+ end
58
+
59
+ def self.eq?(result, expected)
60
+ result.is_a?(expected.class) && result == expected
61
+ end
62
+ end
63
+
64
+ Object.include(Suggest::Mixin)
data/suggest.gemspec ADDED
@@ -0,0 +1,29 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "suggest/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "suggest_rb"
8
+ spec.version = Suggest::VERSION
9
+ spec.authors = ["Josh Bodah"]
10
+ spec.email = ["jbodah@cargurus.com"]
11
+
12
+ spec.summary = %q{tells you which method does the thing you want to do}
13
+ spec.homepage = "https://github.com/jbodah/suggest_rb"
14
+
15
+ # Specify which files should be added to the gem when it is released.
16
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
17
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.17"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "minitest", "~> 5.0"
27
+ spec.add_development_dependency "minitest-tagz"
28
+ spec.add_development_dependency "pry-byebug"
29
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: suggest_rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Josh Bodah
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-01-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-tagz
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - jbodah@cargurus.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - Gemfile
93
+ - README.md
94
+ - Rakefile
95
+ - bin/console
96
+ - bin/setup
97
+ - lib/suggest.rb
98
+ - lib/suggest/version.rb
99
+ - suggest.gemspec
100
+ homepage: https://github.com/jbodah/suggest_rb
101
+ licenses: []
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.5.2.3
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: tells you which method does the thing you want to do
123
+ test_files: []