-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sam Livingston-Gray
committed
Feb 8, 2011
0 parents
commit 66026ea
Showing
10 changed files
with
305 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright (c) 2011 [name of plugin creator] | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
HighlandAR | ||
========== | ||
|
||
Introduction goes here. | ||
|
||
|
||
Example | ||
======= | ||
|
||
Example goes here. | ||
|
||
|
||
Copyright (c) 2011 [name of plugin creator], released under the MIT license |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require 'rake' | ||
require 'rake/testtask' | ||
require 'rake/rdoctask' | ||
|
||
desc 'Default: run unit tests.' | ||
task :default => :test | ||
|
||
desc 'Test the highland_ar plugin.' | ||
Rake::TestTask.new(:test) do |t| | ||
t.libs << 'lib' | ||
t.libs << 'test' | ||
t.pattern = 'test/**/*_test.rb' | ||
t.verbose = true | ||
end | ||
|
||
desc 'Generate documentation for the highland_ar plugin.' | ||
Rake::RDocTask.new(:rdoc) do |rdoc| | ||
rdoc.rdoc_dir = 'rdoc' | ||
rdoc.title = 'HighlandAR' | ||
rdoc.options << '--line-numbers' << '--inline-source' | ||
rdoc.rdoc_files.include('README') | ||
rdoc.rdoc_files.include('lib/**/*.rb') | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Include hook code here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Install hook code here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
module HighlandAR | ||
module ClassMethods | ||
# There are no options. THERE CAN BE ONLY ONE! | ||
def there_can_be_only_one(association_name) | ||
# puts "There can be only one #{association_name} in #{self}!" | ||
has_one association_name | ||
define_tcboo_setter(association_name) | ||
end | ||
|
||
protected | ||
def define_tcboo_setter(association_name) | ||
define_method "#{association_name}_with_immortal_combat=" do |*combatants| | ||
champion = tcboo_tournament(combatants.flatten) | ||
self.send(:"#{association_name}_without_immortal_combat=", champion) | ||
end | ||
alias_method_chain :"#{association_name}=", :immortal_combat | ||
end | ||
end | ||
|
||
module InstanceMethods | ||
# The "tcboo_" prefix is there in case of namespacing conflicts. As if anyone was going to use this. | ||
|
||
protected | ||
def tcboo_power_for(combatant) | ||
@power_rankings ||= {} | ||
@power_rankings[combatant] ||= (1 + rand(10)) | ||
end | ||
def tcboo_set_power_for(combatant, new_power) | ||
@power_rankings[combatant] = new_power | ||
end | ||
|
||
def tcboo_tournament(combatants) | ||
@power_rankings = {} # Start each tournament with a level playing field. Also: thread safety? In a joke plugin? Um... no. | ||
|
||
while combatants.length > 1 | ||
current_round_winners = [] | ||
tcboo_shuffle_combatants(combatants).each_slice(2) do |a, b| | ||
current_round_winners << tcboo_immortal_combat(a, b) | ||
end | ||
combatants = current_round_winners | ||
end | ||
|
||
combatants.first | ||
end | ||
|
||
# Shuffle the array to avoid being unfair to the Nth combatant in a list of N combatants where N is odd. | ||
# Do it in a separate function for mockability. | ||
def tcboo_shuffle_combatants(combatants) | ||
combatants.shuffle | ||
end | ||
|
||
# Two men enter! One man leaves! | ||
# ...oops, sorry, wrong franchise. | ||
def tcboo_immortal_combat(a, b) | ||
ap, bp = tcboo_power_for(a), tcboo_power_for(b) | ||
|
||
if b.nil? | ||
puts "#{a} (#{ap}) wins this match by virtue of being the odd entity out" if $debug | ||
return a | ||
end | ||
|
||
total_power = ap + bp | ||
winner = (rand(1 + total_power) <= ap) ? a : b | ||
loser = (winner == a ? b : a) | ||
tcboo_set_power_for winner, total_power | ||
tcboo_set_power_for loser, 0 | ||
puts "In a fight between #{a} (#{ap}) and #{b} (#{bp}), who would win? #{winner} (#{total_power})!" if $debug | ||
winner | ||
end | ||
end | ||
|
||
def self.included(receiver) | ||
receiver.extend ClassMethods | ||
receiver.send :include, InstanceMethods | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# desc "Explaining what the task does" | ||
# task :highland_ar do | ||
# # Task goes here | ||
# end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
require File.join(File.dirname(__FILE__), *%w[test_helper]) | ||
|
||
class HighlandARModuleTest < HighlandARTestCase | ||
test "module is loadable" do | ||
assert_nothing_raised(NameError) { HighlandAR } | ||
assert_kind_of(Module, HighlandAR) | ||
end | ||
|
||
test "module gives includers a .there_can_be_only_one macro" do | ||
Platypus = new_highlandar_class | ||
assert_nothing_raised(NoMethodError) { Platypus.there_can_be_only_one :bill } | ||
end | ||
|
||
test "calling the macro invokes .has_one" do | ||
Alpaca = new_highlandar_class | ||
Alpaca.expects(:has_one).with(:spitoon) | ||
Alpaca.stubs(:define_tcboo_setter) | ||
Alpaca.there_can_be_only_one :spitoon | ||
end | ||
|
||
test "calling the macro invokes .define_tcboo_setter" do | ||
Chimera = new_highlandar_class | ||
Chimera.expects(:define_tcboo_setter).with(:snake_head) | ||
Chimera.there_can_be_only_one :snake_head | ||
end | ||
|
||
test ".define_tcboo_setter does what it says" do | ||
Chinchilla = new_highlandar_class | ||
Chinchilla.there_can_be_only_one :cute_little_dust_bath_basin | ||
|
||
assert Chinchilla.instance_methods.include?('cute_little_dust_bath_basin='), 'wanted setter' | ||
assert Chinchilla.instance_methods.include?('cute_little_dust_bath_basin_without_immortal_combat='), 'wanted old setter too' | ||
end | ||
end | ||
|
||
class TCBOO_SetterTest < HighlandARTestCase | ||
class Arena < NotActuallyActiveRecordBase | ||
include HighlandAR | ||
there_can_be_only_one :champion | ||
end | ||
|
||
def setup | ||
@arena = Arena.new | ||
end | ||
|
||
test "single contestant is automatically selected -- argument as object" do | ||
@arena.expects(:tcboo_immortal_combat).never | ||
@arena.champion = 'Fred' | ||
assert_equal('Fred', @arena.champion) | ||
end | ||
|
||
test "single contestant is automatically selected -- argument as array" do | ||
@arena.expects(:tcboo_immortal_combat).never | ||
@arena.champion = %w[Fred] | ||
assert_equal('Fred', @arena.champion) | ||
end | ||
|
||
test "champion selection functions as a playoff tree, two entrants" do | ||
@arena.expects(:tcboo_immortal_combat).with('Fred', 'George').returns('George') | ||
@arena.champion = %w[Fred George] | ||
assert_equal('George', @arena.champion) | ||
end | ||
|
||
test "champion selection functions as a playoff tree, three entrants" do | ||
# Round 1 | ||
@arena.expects(:tcboo_shuffle_combatants).with(%w[Fred George Ron]).returns(%w[Fred George Ron]) | ||
@arena.expects(:tcboo_immortal_combat).with('Fred', 'George').returns('George') | ||
@arena.expects(:tcboo_immortal_combat).with('Ron', nil).returns('Ron') | ||
|
||
# Round 2 | ||
@arena.expects(:tcboo_shuffle_combatants).with(%w[George Ron]).returns(%w[George Ron]) | ||
@arena.expects(:tcboo_immortal_combat).with('George', 'Ron').returns('George') | ||
|
||
@arena.champion = %w[Fred George Ron] | ||
assert_equal('George', @arena.champion) | ||
end | ||
|
||
test "champion selection functions as a playoff tree, four entrants" do | ||
# Round 1 | ||
@arena.expects(:tcboo_shuffle_combatants).with(%w[Fred George Ron Harry]).returns(%w[Fred George Ron Harry]) | ||
@arena.expects(:tcboo_immortal_combat).with('Fred', 'George').returns('Fred') | ||
@arena.expects(:tcboo_immortal_combat).with('Ron', 'Harry').returns('Hermione') # just making sure you're paying attention | ||
|
||
# Round 2 | ||
@arena.expects(:tcboo_shuffle_combatants).with(%w[Fred Hermione]).returns(%w[Fred Hermione]) | ||
@arena.expects(:tcboo_immortal_combat).with('Fred', 'Hermione').returns('Hermione') | ||
|
||
@arena.champion = %w[Fred George Ron Harry] | ||
assert_equal('Hermione', @arena.champion) | ||
end | ||
|
||
test "champion selection functions as a playoff tree, nine entrants" do | ||
# Round 1 | ||
@arena.expects(:tcboo_shuffle_combatants).with(%w[A B C D E F G H I]).returns(%w[A B C D E F G H I]) | ||
@arena.expects(:tcboo_immortal_combat).with('A', 'B').returns('A') | ||
@arena.expects(:tcboo_immortal_combat).with('C', 'D').returns('C') # just making sure you're paying attention | ||
@arena.expects(:tcboo_immortal_combat).with('E', 'F').returns('E') | ||
@arena.expects(:tcboo_immortal_combat).with('G', 'H').returns('G') | ||
@arena.expects(:tcboo_immortal_combat).with('I', nil).returns('I') | ||
|
||
# Round 2 | ||
@arena.expects(:tcboo_shuffle_combatants).with(%w[A C E G I]).returns(%w[A C E G I]) | ||
@arena.expects(:tcboo_immortal_combat).with('A', 'C').returns('C') | ||
@arena.expects(:tcboo_immortal_combat).with('E', 'G').returns('G') | ||
@arena.expects(:tcboo_immortal_combat).with('I', nil).returns('I') # CGI. Get it? CGI! ... sheesh. tough room. | ||
|
||
# Round 3 | ||
@arena.expects(:tcboo_shuffle_combatants).with(%w[C G I]).returns(%w[C G I]) | ||
@arena.expects(:tcboo_immortal_combat).with('C', 'G').returns('G') | ||
@arena.expects(:tcboo_immortal_combat).with('I', nil).returns('I') # Knowing is half the battle. | ||
|
||
# Round 4 | ||
@arena.expects(:tcboo_shuffle_combatants).with(%w[G I]).returns(%w[G I]) | ||
@arena.expects(:tcboo_immortal_combat).with('G', 'I').returns('I') # Co-champions: 'Me', 'Myself'. | ||
|
||
@arena.champion = %w[A B C D E F G H I] | ||
assert_equal('I', @arena.champion) | ||
end | ||
|
||
test "this test should actually be random; I include it solely for the amusing side effects" do | ||
begin | ||
puts '' | ||
$debug = true | ||
@arena.champion = %w[Harry Ron Hermione Hagrid Dumbledore Snape RandomBystander Tweedledee Alice] | ||
ensure | ||
$debug = false | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
require 'rubygems' | ||
require 'test/unit' | ||
require 'active_support' | ||
require 'active_support/test_case' | ||
require 'mocha' | ||
require 'ruby-debug' | ||
|
||
require File.join(File.dirname(__FILE__), *%w[.. lib highland_ar]) | ||
|
||
# I hear #send(:include, Foo) doesn't work in 1.9. | ||
# Apparently they're a lot more strict in The Future. | ||
class NotActuallyActiveRecordBase | ||
def self.pretty_please_include_this_module(the_module) | ||
include the_module | ||
end | ||
def self.has_one(association_name) | ||
define_method "#{association_name}=" do |obj| | ||
instance_variable_set("@#{association_name}", obj) | ||
end | ||
define_method association_name do | ||
instance_variable_get("@#{association_name}") | ||
end | ||
end | ||
end | ||
|
||
class HighlandARTestCase < ActiveSupport::TestCase | ||
def new_highlandar_class(*tcboo_methods) | ||
Class.new(NotActuallyActiveRecordBase).tap do |klass| | ||
klass.pretty_please_include_this_module(HighlandAR) | ||
tcboo_methods.each { |e| klass.there_can_be_only_one(e) } | ||
end | ||
end | ||
|
||
def deny(condition, *args) | ||
assert !condition, *args | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Uninstall hook code here |