higher_expectations 0.0.1 → 0.0.2
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.
- data/History.txt +4 -0
- data/Manifest.txt +1 -1
- data/README.txt +22 -17
- data/Rakefile +21 -1
- data/lib/{version.rb → higher_expectations/version.rb} +1 -1
- data/lib/higher_expectations.rb +2 -2
- data/lib/instance_methods.rb +5 -1
- data/spec/instance_methods_spec.rb +1 -1
- data/website/index.html +86 -11
- metadata +2 -2
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= higher_expectations
|
2
2
|
|
3
|
-
* http://
|
3
|
+
* http://higher-expect.rubyforge.org
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
@@ -29,23 +29,23 @@ end
|
|
29
29
|
* Please note that this is alpha software
|
30
30
|
* Provides a set of usefull methods for determining what an object is at runtime, and raising an exception
|
31
31
|
* Avoids creating these methods in Object directly, and instead extends the objects passed in (although it does add them directly to Numeric due to constraints in Ruby's Numeric implementation)
|
32
|
-
* Allows for method
|
32
|
+
* Allows for method chaining to provide a dose of syntactic sugar
|
33
33
|
|
34
34
|
== SYNOPSIS:
|
35
35
|
|
36
|
-
Imagine you have a method to calculate sunrise buried within a 1D planet simulator codebase. Throughout the codebase, validations are used to check data input, and there is a well
|
36
|
+
Imagine you have a method to calculate sunrise buried within a 1D planet simulator codebase. Throughout the codebase, validations are used to check data input, and there is a well thoughtout and well written test suite.
|
37
37
|
|
38
38
|
def calc_sunrise(day, month)
|
39
39
|
sunrise = (day - 50000)/month # arbitrary calculation that assumes day is a number and not negative
|
40
40
|
end
|
41
41
|
|
42
|
-
However, Joey your coworker hacks and calls the following function:
|
42
|
+
However, Joey your coworker hacks away and calls the following function:
|
43
43
|
|
44
44
|
PlanetEarth.sunrise = calc_sunrise(-5, 1)
|
45
45
|
|
46
46
|
Code executes, no exceptions are raised, but earths sunrise changes to a weird value. No amount of unit testing, specing, validating outside the model would have stopped Joey from making this hambone maneuver.
|
47
47
|
|
48
|
-
|
48
|
+
Checking the arguments within the method would have prevented this:
|
49
49
|
|
50
50
|
def calc_sunrise(day, month)
|
51
51
|
raise ArgumentError.new("day must be numeric") unless day.kind_of?(Numeric)
|
@@ -56,24 +56,29 @@ def calc_sunrise(day, month)
|
|
56
56
|
...sunrise calc...
|
57
57
|
end
|
58
58
|
|
59
|
-
|
59
|
+
But writing this sort of code is slow and error prone. Wouldn't you like to do this instead?
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
61
|
+
require 'higher_expectations'
|
62
|
+
class PlanetCalculations
|
63
|
+
include HigherExpectations
|
64
|
+
def calc_sunrise(day, month)
|
65
|
+
has_expectations(day, month) # attach expectation methods to each object
|
66
|
+
day.must_be_an(Integer) # day must kind_of? Integer or an exception will be raised
|
67
|
+
day.must_be_in_range(1..31) # day must be in the given range or exception
|
68
|
+
# a neat combination of both
|
69
|
+
month.must_be_an(Integer).and_must_be_in_range(1..31)
|
70
|
+
# since it raises an exception, its trappable, allowing for more flexible handling
|
71
|
+
month.must_be_nil rescue ArgumentError nil
|
72
|
+
...sunrise calc
|
73
|
+
end
|
69
74
|
end
|
70
75
|
|
71
|
-
...
|
76
|
+
...without comments:
|
72
77
|
|
73
78
|
def calc_sunrise(day,month)
|
74
79
|
has_expectations(day,month)
|
75
|
-
|
76
|
-
month.
|
80
|
+
day.must_be_a(Integer).and_must_be_in_range(1..31)
|
81
|
+
month.must_be_a(Integer).and_must_be_in_range(1..31
|
77
82
|
...sunrise calc...
|
78
83
|
end
|
79
84
|
|
data/Rakefile
CHANGED
@@ -1,4 +1,24 @@
|
|
1
1
|
require 'config/requirements'
|
2
2
|
require 'config/hoe' # setup Hoe + all gem configuration
|
3
3
|
|
4
|
-
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
4
|
+
Dir['tasks/**/*.rake'].each { |rake| load rake }
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'spec/rake/spectask'
|
8
|
+
|
9
|
+
Spec::Rake::SpecTask.new("spec") do |t|
|
10
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
11
|
+
t.spec_opts = ['--color']
|
12
|
+
end
|
13
|
+
|
14
|
+
task :test do
|
15
|
+
Rake::Task['spec'].invoke
|
16
|
+
end
|
17
|
+
|
18
|
+
Spec::Rake::SpecTask.new("rcov_spec") do |t|
|
19
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
20
|
+
t.spec_opts = ['--color']
|
21
|
+
t.rcov = true
|
22
|
+
t.rcov_opts = ['--exclude', '^spec,/gems/']
|
23
|
+
end
|
24
|
+
end
|
data/lib/higher_expectations.rb
CHANGED
@@ -17,10 +17,10 @@ require 'instance_methods'
|
|
17
17
|
module HigherExpectations
|
18
18
|
VERSION = '0.1.0'
|
19
19
|
|
20
|
-
# Should be called at method entrance
|
21
|
-
# instead of spaming up entire Object class method space, extend each given object with expectation methods
|
20
|
+
# Should be called at method entrance, extends each given object with expectation methods
|
22
21
|
def has_expectations(*objects)
|
23
22
|
objects.map do |obj|
|
23
|
+
#next if obj.respond_to?(:raise_ae) # skip objects that have already instance methods
|
24
24
|
begin
|
25
25
|
obj.extend(HigherExpectations::InstanceMethods)
|
26
26
|
# TypeErrors are generated when trying to extend Numeric objects, which are not and cannot be singeltons and hence cannot get new methods.
|
data/lib/instance_methods.rb
CHANGED
@@ -45,7 +45,9 @@ module HigherExpectations
|
|
45
45
|
end
|
46
46
|
self
|
47
47
|
end
|
48
|
-
alias :
|
48
|
+
alias :must_be_an :must_be_a
|
49
|
+
|
50
|
+
|
49
51
|
|
50
52
|
# value(s) must not be in a specific class or set of klasses
|
51
53
|
def must_not_be_a(*klasses)
|
@@ -54,7 +56,9 @@ module HigherExpectations
|
|
54
56
|
end
|
55
57
|
self
|
56
58
|
end
|
59
|
+
alias :must_not_be_an :must_not_be_a
|
57
60
|
alias :and_must_not_be_a :must_not_be_a
|
61
|
+
alias :and_must_not_be_an :must_not_be_a
|
58
62
|
|
59
63
|
# value(s) must be in a specific numeric range
|
60
64
|
def must_be_in_range(range)
|
@@ -6,7 +6,7 @@ end
|
|
6
6
|
#
|
7
7
|
# Todo: a clever implementation that DRYs up the below, while leaving it readable and producing a decent specdoc
|
8
8
|
#
|
9
|
-
describe "InstanceMethods" do
|
9
|
+
describe "HigherExpectation::InstanceMethods" do
|
10
10
|
include HigherExpectations
|
11
11
|
before(:each) do
|
12
12
|
@number = 1
|
data/website/index.html
CHANGED
@@ -1,11 +1,86 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
|
+
<title>
|
8
|
+
higher_expectations
|
9
|
+
</title>
|
10
|
+
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
11
|
+
<style>
|
12
|
+
|
13
|
+
</style>
|
14
|
+
<script type="text/javascript">
|
15
|
+
window.onload = function() {
|
16
|
+
settings = {
|
17
|
+
tl: { radius: 10 },
|
18
|
+
tr: { radius: 10 },
|
19
|
+
bl: { radius: 10 },
|
20
|
+
br: { radius: 10 },
|
21
|
+
antiAlias: true,
|
22
|
+
autoPad: true,
|
23
|
+
validTags: ["div"]
|
24
|
+
}
|
25
|
+
var versionBox = new curvyCorners(settings, document.getElementById("version"));
|
26
|
+
versionBox.applyCornersToAll();
|
27
|
+
}
|
28
|
+
</script>
|
29
|
+
</head>
|
30
|
+
<body>
|
31
|
+
<div id="main">
|
32
|
+
|
33
|
+
<h1>higher_expectations</h1>
|
34
|
+
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/higher_expectations"; return false'>
|
35
|
+
<p>Get Version</p>
|
36
|
+
<a href="http://rubyforge.org/projects/higher_expectations" class="numbers">0.0.2</a>
|
37
|
+
</div>
|
38
|
+
<h1>&#x2192; ‘higher_expectations’</h1>
|
39
|
+
<h2>What</h2>
|
40
|
+
<h2>Installing</h2>
|
41
|
+
<p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">higher_expectations</span></pre></p>
|
42
|
+
<h2>The basics</h2>
|
43
|
+
<h2>Demonstration of usage</h2>
|
44
|
+
<h2>Forum</h2>
|
45
|
+
<p><a href="http://groups.google.com/group/higher_expectations">http://groups.google.com/group/higher_expectations</a></p>
|
46
|
+
<p><span class="caps">TODO</span> – create Google Group – higher_expectations</p>
|
47
|
+
<h2>How to submit patches</h2>
|
48
|
+
<p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people’s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
|
49
|
+
<p><span class="caps">TODO</span> – pick <span class="caps">SVN</span> or Git instructions</p>
|
50
|
+
<p>The trunk repository is <code>svn://rubyforge.org/var/svn/higher_expectations/trunk</code> for anonymous access.</p>
|
51
|
+
<p><span class="caps">OOOORRRR</span></p>
|
52
|
+
<p>You can fetch the source from either:</p>
|
53
|
+
<ul>
|
54
|
+
<li>rubyforge: <span class="caps">MISSING</span> IN <span class="caps">ACTION</span></li>
|
55
|
+
</ul>
|
56
|
+
<p><span class="caps">TODO</span> – You can not created a RubyForge project, OR have not run <code>rubyforge config</code><br />
|
57
|
+
yet to refresh your local rubyforge data with this projects’ id information.</p>
|
58
|
+
<p>When you do this, this message will magically disappear!</p>
|
59
|
+
<p>Or you can hack website/index.txt and make it all go away!!</p>
|
60
|
+
<ul>
|
61
|
+
<li>github: <a href="http://github.com/GITHUB_USERNAME/higher_expectations/tree/master">http://github.com/GITHUB_USERNAME/higher_expectations/tree/master</a></li>
|
62
|
+
</ul>
|
63
|
+
<pre>git clone git://github.com/GITHUB_USERNAME/higher_expectations.git</pre>
|
64
|
+
<p><span class="caps">TODO</span> – add “github_username: username” to ~/.rubyforge/user-config.yml and newgem will reuse it for future projects.</p>
|
65
|
+
<ul>
|
66
|
+
<li>gitorious: <a href="git://gitorious.org/higher_expectations/mainline.git">git://gitorious.org/higher_expectations/mainline.git</a></li>
|
67
|
+
</ul>
|
68
|
+
<pre>git clone git://gitorious.org/higher_expectations/mainline.git</pre>
|
69
|
+
<h3>Build and test instructions</h3>
|
70
|
+
<pre>cd higher_expectations
|
71
|
+
rake test
|
72
|
+
rake install_gem</pre>
|
73
|
+
<h2>License</h2>
|
74
|
+
<p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
|
75
|
+
<h2>Contact</h2>
|
76
|
+
<p>Comments are welcome. Send an email to <a href="mailto:FIXME"><span class="caps">FIXME</span> full name</a> email via the <a href="http://groups.google.com/group/higher_expectations">forum</a></p>
|
77
|
+
<p class="coda">
|
78
|
+
<a href="FIXME email">FIXME full name</a>, 14th August 2008<br>
|
79
|
+
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
80
|
+
</p>
|
81
|
+
</div>
|
82
|
+
|
83
|
+
<!-- insert site tracking codes here, like Google Urchin -->
|
84
|
+
|
85
|
+
</body>
|
86
|
+
</html>
|
metadata
CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: higher_expectations
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
6
|
+
version: 0.0.2
|
7
7
|
date: 2008-08-14 00:00:00 -04:00
|
8
8
|
summary: description of gem
|
9
9
|
require_paths:
|
@@ -39,7 +39,7 @@ files:
|
|
39
39
|
- config/requirements.rb
|
40
40
|
- lib/higher_expectations.rb
|
41
41
|
- lib/instance_methods.rb
|
42
|
-
- lib/version.rb
|
42
|
+
- lib/higher_expectations/version.rb
|
43
43
|
- script/console
|
44
44
|
- script/console.cmd
|
45
45
|
- script/destroy
|