gendarme 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ *.swp
5
+ Gemfile.lock
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2@gendarme
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Franck Verrot
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,63 @@
1
+ # Gendarme
2
+
3
+ ## Introductio
4
+
5
+ Gendarme will bring order to chaos (well... that's the role of Gendarme ma bonne Dame...).
6
+ Gendarme checks for preconditions and postrelations on the methods you want it to monitor.
7
+
8
+ It does not replace a regular test framework (Rspec, Test::Unit,
9
+ you-name-it), it all started when I have been asked how to replicate an
10
+ annotation system with Ruby. This is more or less how I would implement
11
+ it in real life (but I highly doubt I would ever want to do that).
12
+
13
+ ## Usage
14
+
15
+ Put this in your Gemfile:
16
+
17
+ gem install gendarme
18
+
19
+ Once Gendarme is installed, add it to your classes:
20
+
21
+ # Eventually configure where you want the messages to be displayed
22
+ Gendarme::Configuration.logger = $stderr # Standard error
23
+
24
+ class Foo
25
+ include Gendarme::Gendarme # Add Gendarme's method to your class
26
+
27
+ precondition(0,"Argument 0 is a String") { |bar| bar.respond_to?(:to_str) }
28
+ precondition(1,"Argument 1 is 10") { |baz| baz == 10 }
29
+ postrelation(0,"Result is an Integer") { |res| res.is_a?(Integer)}
30
+ def foo(bar,baz)
31
+ ...
32
+ "not an integer"
33
+ end
34
+ end
35
+
36
+ # Now let's try it, neither the inputs nor the output are valid
37
+ Foo.new.foo(42, "hello")
38
+ => "not an integer"
39
+
40
+ # You should see this in the standard error output
41
+ This precondition is false: Argument 0 is a String
42
+ This precondition is false: Argument 1 is 10
43
+ This postrelation is false: Result is an Integer
44
+
45
+ ##Note on Patches/Pull Requests
46
+
47
+ * Fork the project.
48
+ * Make your feature addition or bug fix.
49
+ * Add tests for it. This is important so I don't break it in a
50
+ future version unintentionally.
51
+ * Commit, do not mess with rakefile, version, or history.
52
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
53
+ * Send me a pull request. Bonus points for topic branches.
54
+
55
+
56
+ Contributors
57
+ ------------
58
+ * Franck Verrot
59
+
60
+ Copyright
61
+ ---------
62
+
63
+ Copyright (c) 2010 Franck Verrot. MIT LICENSE. See LICENSE for details.
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.unshift File.expand_path("../lib", __FILE__)
3
+
4
+ require 'rubygems'
5
+ require 'rubygems/specification'
6
+ require 'gendarme'
7
+
8
+ begin
9
+ require 'rspec/core/rake_task'
10
+
11
+ desc "Run specs"
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.rspec_opts = %w(-fs --color)
14
+ t.ruby_opts = %w(-w)
15
+ end
16
+
17
+ rescue LoadError
18
+ task :spec do
19
+ abort "Run `gem install rspec` to be able to run specs"
20
+ end
21
+ end
22
+
23
+ task :default => :spec
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "gendarme/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "gendarme"
7
+ s.version = Gendarme::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Franck Verrot"]
10
+ s.email = ["franck@verrot.fr"]
11
+ s.homepage = "https://github.com/cesario/gendarme"
12
+ #0 Gendarmes have been during the implementation of that gem, I promise
13
+ s.summary = %q{Gendarme will bring order to chaos (well... that's the role of Gendarme ma bonne Dame...)}
14
+ s.description = %q{Gendarme checks for preconditions and postrelations on the methods you want it to.}
15
+
16
+ s.rubyforge_project = "gendarme"
17
+
18
+ s.add_dependency 'activesupport'
19
+ s.add_dependency 'i18n'
20
+
21
+ s.add_development_dependency 'rspec'
22
+ s.add_development_dependency 'rspec-core'
23
+ s.add_development_dependency 'rspec-expectations'
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.require_paths = ["lib"]
29
+ end
@@ -0,0 +1,7 @@
1
+ require 'active_support'
2
+ module Gendarme
3
+ extend ActiveSupport::Concern
4
+ autoload :Configuration, 'gendarme/configuration'
5
+ autoload :Gendarme , 'gendarme/gendarme'
6
+ end
7
+
@@ -0,0 +1,13 @@
1
+ module Gendarme
2
+ class Configuration
3
+ class << self
4
+ attr_accessor :log_stream
5
+ def logger=(log)
6
+ self.log_stream = log
7
+ end
8
+ def logger
9
+ self.log_stream
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,75 @@
1
+ module Gendarme
2
+ module Gendarme
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ attr_accessor :metadata
7
+ def apply_gendarme_rules(m)
8
+ class_eval do
9
+ alias :"original_#{m}" :"#{m}"
10
+ define_method :"process_preconditions_on_#{m}" do |*args|
11
+ preconditions = self.class.metadata[m][:preconditions]
12
+ method = self.class.instance_method(m)
13
+ preconditions.each_pair do |parameter_position, precondition|
14
+ Configuration.logger.puts "Won't validate a nil parameter##{parameter_position}" if args[parameter_position].nil?
15
+ unless precondition[:block].call(args[parameter_position])
16
+ Configuration.logger.puts "This precondition is false: #{precondition[:message]}"
17
+ end
18
+ end
19
+ end
20
+
21
+ define_method :"process_postrelations_on_#{m}" do |result|
22
+ postrelations = self.class.metadata[m][:postrelations]
23
+ postrelations.each_pair do |assertion_number, postrelation|
24
+ expected_assertion = postrelation[:block].call(result)
25
+ unless expected_assertion
26
+ Configuration.logger.puts "This postrelation is false: #{postrelation[:message]}"
27
+ end
28
+ end if postrelations
29
+
30
+ result
31
+ end
32
+
33
+ define_method(m) do |*args|
34
+ send(:"process_preconditions_on_#{m}", *args)
35
+ result = send(:"original_#{m}", *args)
36
+ send(:"process_postrelations_on_#{m}", result)
37
+ end
38
+ end
39
+ #end
40
+ end
41
+
42
+ def clear_metadata
43
+ @__current_preconditions = @__current_postrelations = nil
44
+ end
45
+
46
+ def precondition(parameter, message, &block)
47
+ @__current_preconditions ||= {}
48
+ @__current_preconditions[parameter] = { :message => message, :block => block }
49
+ end
50
+
51
+ def postrelation(parameter, message, &block)
52
+ @__current_postrelations ||= {}
53
+ @__current_postrelations[parameter]= { :message => message, :block => block }
54
+
55
+ end
56
+
57
+ def method_added(m)
58
+ @already_processed ||= []
59
+
60
+ return if /^(original_|process_)/ =~ m or @already_processed.include?(m)
61
+
62
+ @already_processed << m
63
+ @__last_method = m
64
+
65
+ self.metadata ||= {}
66
+ self.metadata[@__last_method] = {
67
+ :preconditions => @__current_preconditions,
68
+ :postrelations => @__current_postrelations
69
+ }
70
+ clear_metadata
71
+ apply_gendarme_rules(m)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ module Gendarme
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+
3
+ class Foo
4
+ include Gendarme::Gendarme
5
+
6
+ #Should be OK
7
+ precondition(0,"Bar responds to :to_i") { |bar| bar.respond_to? :to_i }
8
+ #Should not be OK
9
+ precondition(0,"Bar responds to :to_str") { |bar| bar.respond_to? :to_str }
10
+ #Should be OK
11
+ postrelation(0,"Result is an integer") { |result| result.is_a?(Integer) }
12
+ #Should not be OK
13
+ postrelation(0,"Result is a string") { |result| result.is_a?(String) }
14
+ def foo(bar)
15
+ bar * 2
16
+ end
17
+ end
18
+
19
+ describe "Gendarme" do
20
+ describe "should print to stderr" do
21
+ before(:each) do
22
+ Gendarme::Configuration.logger = $stderr
23
+ end
24
+
25
+ it "on failed preconditons and failed preconditions" do
26
+ output = capture(:stdout,:stderr) do
27
+ Foo.new.foo(2)
28
+ end
29
+ output.should == /failed/
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ require 'active_support'
2
+ require 'gendarme'
3
+
4
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb' ))].each {|f| require f}
5
+
6
+ RSpec.configure do |rspec_config|
7
+ end
@@ -0,0 +1,13 @@
1
+ require 'stringio'
2
+ def capture(*streams)
3
+ streams.map! { |stream| stream.to_s }
4
+ begin
5
+ result = StringIO.new
6
+ streams.each { |stream| eval "$#{stream} = result" }
7
+ yield
8
+ ensure
9
+ streams.each { |stream| eval("$#{stream} = #{stream.upcase}") }
10
+ end
11
+ result.string
12
+ end
13
+
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gendarme
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Franck Verrot
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-12-19 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: i18n
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: rspec-core
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :development
71
+ version_requirements: *id004
72
+ - !ruby/object:Gem::Dependency
73
+ name: rspec-expectations
74
+ prerelease: false
75
+ requirement: &id005 !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
83
+ type: :development
84
+ version_requirements: *id005
85
+ description: Gendarme checks for preconditions and postrelations on the methods you want it to.
86
+ email:
87
+ - franck@verrot.fr
88
+ executables: []
89
+
90
+ extensions: []
91
+
92
+ extra_rdoc_files: []
93
+
94
+ files:
95
+ - .gitignore
96
+ - .rvmrc
97
+ - Gemfile
98
+ - LICENSE
99
+ - README.md
100
+ - Rakefile
101
+ - gendarme.gemspec
102
+ - lib/gendarme.rb
103
+ - lib/gendarme/configuration.rb
104
+ - lib/gendarme/gendarme.rb
105
+ - lib/gendarme/version.rb
106
+ - spec/gendarme_spec.rb
107
+ - spec/spec_helper.rb
108
+ - spec/support/capture.rb
109
+ has_rdoc: true
110
+ homepage: https://github.com/cesario/gendarme
111
+ licenses: []
112
+
113
+ post_install_message:
114
+ rdoc_options: []
115
+
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ segments:
132
+ - 0
133
+ version: "0"
134
+ requirements: []
135
+
136
+ rubyforge_project: gendarme
137
+ rubygems_version: 1.3.7
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Gendarme will bring order to chaos (well... that's the role of Gendarme ma bonne Dame...)
141
+ test_files:
142
+ - spec/gendarme_spec.rb
143
+ - spec/spec_helper.rb
144
+ - spec/support/capture.rb