bringhurst 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 96c05ab54df1c8c8555a51479623a793f8cac7e8
4
+ data.tar.gz: ed4d3decf22d8facb79117b39bb55895b44dd4dc
5
+ SHA512:
6
+ metadata.gz: 3167a6762ce23b31513fec0b16a2a75d72b3cf383f5ded948542fff3bcefbbb7f4696488dc54a4852dab2ed08f86348b6cc1a00d76c94bbee2732cdec73dc288
7
+ data.tar.gz: adcb0a40ac1c84f942c14a9449e7eeff0cd4eba7f3f4b599fd3ab94fa15f93d4921c238fb077d912f3335981a649ed7b5d868e7b2927d72059aed813a457a7ee
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in bringhurst.gemspec
4
+ gemspec
@@ -0,0 +1,129 @@
1
+ # Bringhurst
2
+
3
+ Bringhurst watches you run your methods, infers their types, and formats the
4
+ results. It does this by aliasing each method in a user-defined collection of
5
+ classes and noting the types of their arguments and results.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem "bringhurst"
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```
18
+ $ bundle
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```
24
+ $ gem install bringhurst
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ Once Bringhurst is installed, you'll need to tell it which classes to observe
30
+ and when to display the results. I recommend setting it up in your `spec_helper`
31
+ by doing something like:
32
+
33
+ ```ruby
34
+ require "bringhurst"
35
+
36
+ RSpec.configure do |config|
37
+ # ...
38
+ def observer
39
+ Bringhurst::TypeObserver.instance
40
+ end
41
+
42
+ config.before(:suite) do
43
+ observer.observe_class(Gitsh::CapturingEnvironment)
44
+ observer.observe_class(Gitsh::Completer)
45
+ observer.observe_class(Gitsh::Environment)
46
+ end
47
+
48
+ config.after(:suite) do
49
+ puts Bringhurst::Formatter.new(observer.method_calls)
50
+ end
51
+ # ...
52
+ end
53
+ ```
54
+
55
+ Next, run the tests:
56
+
57
+ ```
58
+ $ rspec
59
+ ```
60
+
61
+ And see the results:
62
+
63
+ ```
64
+ ...........................................
65
+ Observed Type Signatures
66
+ ========================
67
+ Gitsh::CapturingEnvironment#captured_output: String
68
+ Gitsh::CapturingEnvironment#output_stream: IO
69
+ Gitsh::Completer#call: String -> Array
70
+ Gitsh::Environment#[]=: String -> String -> String
71
+ Gitsh::Environment#[]=: Symbol -> String -> String
72
+ Gitsh::Environment#config_variables: Hash
73
+ Gitsh::Environment#error_stream: StringIO
74
+ Gitsh::Environment#fetch: String -> NilClass
75
+ Gitsh::Environment#fetch: String -> String
76
+ Gitsh::Environment#fetch: String -> TrueClass -> String
77
+ Gitsh::Environment#fetch: Symbol -> String
78
+ Gitsh::Environment#git_aliases: Array
79
+ Gitsh::Environment#git_command: FalseClass -> String
80
+ Gitsh::Environment#git_command: String
81
+ Gitsh::Environment#git_command: TrueClass -> String
82
+ Gitsh::Environment#git_command=: String -> String
83
+ Gitsh::Environment#git_commands: RSpec::Mocks::Double
84
+ Gitsh::Environment#input_stream: IO
85
+ Gitsh::Environment#input_stream: RSpec::Mocks::Double
86
+ Gitsh::Environment#output_stream: IO
87
+ Gitsh::Environment#output_stream: RSpec::Mocks::Double
88
+ Gitsh::Environment#output_stream: StringIO
89
+ Gitsh::Environment#print: String -> NilClass
90
+ Gitsh::Environment#puts: String -> NilClass
91
+ Gitsh::Environment#puts_error: String -> NilClass
92
+ Gitsh::Environment#readline_version: String
93
+ Gitsh::Environment#repo_config_color: String -> String -> RSpec::Mocks::Double
94
+ Gitsh::Environment#repo_current_head: RSpec::Mocks::Double
95
+ Gitsh::Environment#repo_has_modified_files?: RSpec::Mocks::Double
96
+ Gitsh::Environment#repo_has_untracked_files?: RSpec::Mocks::Double
97
+ Gitsh::Environment#repo_heads: RSpec::Mocks::Double
98
+ Gitsh::Environment#repo_initialized?: RSpec::Mocks::Double
99
+ Gitsh::Environment#tty?: FalseClass
100
+ Gitsh::Environment#tty?: TrueClass
101
+ ```
102
+
103
+ (I'm hijacking the lovely [gitsh](https://github.com/thoughtbot/gitsh) here for
104
+ my examples.)
105
+
106
+ You can use it in places other than tests, but I wouldn't recommend it -- it'll
107
+ definitely adversely affect performance.
108
+
109
+ ## Development
110
+
111
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
112
+ `rake spec` to run the tests. You can also run `bin/console` for an interactive
113
+ prompt that will allow you to experiment.
114
+
115
+ To install this gem onto your local machine, run `bundle exec rake install`. To
116
+ release a new version, update the version number in `version.rb`, and then run
117
+ `bundle exec rake release`, which will create a git tag for the version, push
118
+ git commits and tags, and push the `.gem` file to
119
+ [rubygems.org](https://rubygems.org).
120
+
121
+ ## Contributing
122
+
123
+ Bug reports and pull requests are welcome on GitHub at
124
+ https://github.com/hrs/bringhurst.
125
+
126
+ ## Weird name.
127
+
128
+ "Bringhurst" references one of my favorite
129
+ [observers of types](https://en.wikipedia.org/wiki/The_Elements_of_Typographic_Style).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "bringhurst"
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
@@ -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,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "bringhurst/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bringhurst"
8
+ spec.version = Bringhurst::VERSION
9
+ spec.authors = ["Harry R. Schwartz"]
10
+ spec.email = ["hello@harryrschwartz.com"]
11
+
12
+ spec.summary = "Infer your methods' types and generate signatures."
13
+ spec.homepage = "https://github.com/hrs/bringhurst"
14
+ spec.license = "GPL-3.0"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.11"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+ end
@@ -0,0 +1,7 @@
1
+ require "bringhurst/version"
2
+ require "bringhurst/formatter"
3
+ require "bringhurst/type_observer"
4
+ require "bringhurst/type_signature"
5
+
6
+ module Bringhurst
7
+ end
@@ -0,0 +1,18 @@
1
+ module Bringhurst
2
+ class Formatter
3
+ def initialize(signatures)
4
+ @signatures = signatures
5
+ end
6
+
7
+ def to_s
8
+ "\n" +
9
+ "Observed Type Signatures\n" +
10
+ "========================\n" +
11
+ signatures.map(&:to_s).uniq.sort.join("\n")
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :signatures
17
+ end
18
+ end
@@ -0,0 +1,102 @@
1
+ require "securerandom"
2
+ require "singleton"
3
+ require_relative "type_signature"
4
+
5
+ module Bringhurst
6
+ class TypeObserver
7
+ include Singleton
8
+
9
+ attr_reader :method_calls
10
+
11
+ def initialize
12
+ @method_calls = []
13
+ end
14
+
15
+ def observe_class(klass)
16
+ wrap_instance_methods_of(klass)
17
+ wrap_class_methods_of(klass)
18
+ end
19
+
20
+ def register_call(signature)
21
+ @method_calls << signature
22
+ end
23
+
24
+ private
25
+
26
+ def wrap_instance_methods_of(klass)
27
+ instance_methods_of(klass).each do |method_name|
28
+ wrap_instance_method(klass, method_name)
29
+ end
30
+ end
31
+
32
+ def wrap_class_methods_of(klass)
33
+ class_methods_of(klass).each do |method_name|
34
+ wrap_class_method(klass, method_name)
35
+ end
36
+ end
37
+
38
+ def wrap_instance_method(klass, method_name)
39
+ aliased_method_name = aliased_method_name_for(method_name)
40
+
41
+ klass.class_eval do
42
+ alias_method(aliased_method_name, method_name)
43
+
44
+ define_method(method_name) do |*args, &block|
45
+ result = public_send(aliased_method_name, *args, &block)
46
+
47
+ Bringhurst::TypeObserver.instance.register_call(
48
+ Bringhurst::TypeSignature.new(
49
+ klass: klass,
50
+ method: method_name,
51
+ method_kind: :instance,
52
+ arguments: args.map(&:class),
53
+ result: result.class,
54
+ ),
55
+ )
56
+
57
+ result
58
+ end
59
+ end
60
+ end
61
+
62
+ def wrap_class_method(klass, method_name)
63
+ aliased_method_name = aliased_method_name_for(method_name)
64
+
65
+ klass.class_eval do
66
+ singleton_class.send(
67
+ :alias_method,
68
+ aliased_method_name,
69
+ method_name,
70
+ )
71
+
72
+ define_singleton_method(method_name) do |*args, &block|
73
+ result = public_send(aliased_method_name, *args, &block)
74
+
75
+ Bringhurst::TypeObserver.instance.register_call(
76
+ Bringhurst::TypeSignature.new(
77
+ klass: klass,
78
+ method: method_name,
79
+ method_kind: :class,
80
+ arguments: args.map(&:class),
81
+ result: result.class,
82
+ ),
83
+ )
84
+
85
+ result
86
+ end
87
+ end
88
+ end
89
+
90
+ def instance_methods_of(klass)
91
+ klass.instance_methods(false)
92
+ end
93
+
94
+ def class_methods_of(klass)
95
+ klass.methods(false)
96
+ end
97
+
98
+ def aliased_method_name_for(method_name)
99
+ "#{ method_name }_#{ SecureRandom.uuid }"
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,36 @@
1
+ module Bringhurst
2
+ class TypeSignature
3
+ attr_reader :klass, :method, :method_kind, :arguments, :result
4
+
5
+ def initialize(klass:, method:, method_kind:, arguments:, result:)
6
+ @klass = klass
7
+ @method = method
8
+ @method_kind = method_kind
9
+ @arguments = arguments
10
+ @result = result
11
+ end
12
+
13
+ def ==(other)
14
+ self.class == other.class &&
15
+ klass == other.klass &&
16
+ method == other.method &&
17
+ method_kind == other.method_kind &&
18
+ arguments == other.arguments &&
19
+ result == other.result
20
+ end
21
+
22
+ def to_s
23
+ "#{ method_name }: #{ (arguments + [result]).map(&:to_s).join(" -> ") }"
24
+ end
25
+
26
+ private
27
+
28
+ def method_name
29
+ if method_kind == :instance
30
+ "#{ klass }##{ method }"
31
+ elsif method_kind == :class
32
+ "#{ klass }.#{ method }"
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Bringhurst
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bringhurst
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Harry R. Schwartz
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-23 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.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description:
56
+ email:
57
+ - hello@harryrschwartz.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/setup
70
+ - bringhurst.gemspec
71
+ - lib/bringhurst.rb
72
+ - lib/bringhurst/formatter.rb
73
+ - lib/bringhurst/type_observer.rb
74
+ - lib/bringhurst/type_signature.rb
75
+ - lib/bringhurst/version.rb
76
+ homepage: https://github.com/hrs/bringhurst
77
+ licenses:
78
+ - GPL-3.0
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.5.1
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Infer your methods' types and generate signatures.
100
+ test_files: []