Saturday, June 18, 2011
Saturday, June 18, 2011
bitcoin                               ==                          con-currency?Saturday, June 18, 2011
Saturday, June 18, 2011
José!    Me!Saturday, June 18, 2011
WWFMD?Saturday, June 18, 2011
Public Service                          AnnouncementsSaturday, June 18, 2011
SIGSEGV is badSaturday, June 18, 2011
neversaydieSaturday, June 18, 2011
begin                  # something dangerous                rescue NeverSayDie                  # fix memory              ...
"Not working in                          production mode"Saturday, June 18, 2011
DO NOT USE THIS                            SOFTWARESaturday, June 18, 2011
ruby -wSaturday, June 18, 2011
def hello                  x = Object.new   # warning                  10 + 10                endSaturday, June 18, 2011
warning: assigned but unused variable - xSaturday, June 18, 2011
How deprecation                   notices SHOULD be                         writtenSaturday, June 18, 2011
class Foo                  def deprecated                    if $VERBOSE                       warn "hey bro, dont call th...
RSpec ProblemSaturday, June 18, 2011
warning: useless use of == in void contextSaturday, June 18, 2011
it "passes" do                  10.should == 10                  11.should == 11                endSaturday, June 18, 2011
def check(thing)                end                def deprecated                  check 10.should == 10                  ...
@tenderloveSaturday, June 18, 2011
AT&T, AT&T logo and all AT&T related marks are trademarks of AT&T Intellectual Property and/or AT&T affiliated companies.S...
Ruby Core TeamSaturday, June 18, 2011
Rails Core TeamSaturday, June 18, 2011
Saturday, June 18, 2011
White GuySaturday, June 18, 2011
Story about                          Geethika and                          pinochle, java, etcSaturday, June 18, 2011
Story about                            Geethika and                            pinochle, java, etc                        ...
<3 <3 <3Saturday, June 18, 2011
"Congratulations, you just                  made us not consider Rails                 for anything anymore despite       ...
SWEDEN!Saturday, June 18, 2011
IKEA!Saturday, June 18, 2011
MEATBALLS!Saturday, June 18, 2011
SWEDISH FISH!Saturday, June 18, 2011
Made in Canada!Saturday, June 18, 2011
Made in Canada!Saturday, June 18, 2011
How do you catch                           such tiny fish?Saturday, June 18, 2011
Will you share your                            Swedish Fish                            Fishing spot?Saturday, June 18, 2011
Talk about                                      Rails,                                      Talk about                    ...
Legacy CodeSaturday, June 18, 2011
What is                          Legacy Code?Saturday, June 18, 2011
UntestedSaturday, June 18, 2011
OldSaturday, June 18, 2011
Maintainers                                      are gone                          Not UnderstoodSaturday, June 18, 2011
Importance of                           Legacy CodeSaturday, June 18, 2011
Old code contains                             KnowledgeSaturday, June 18, 2011
Solves Todays                            ProblemsSaturday, June 18, 2011
All Legacy Code is                               Not EqualSaturday, June 18, 2011
Tenderlove                          Tear FormulaSaturday, June 18, 2011
Code Burden          Tears                              TimeSaturday, June 18, 2011
Tears cried at time TSaturday, June 18, 2011
Volume at time TSaturday, June 18, 2011
Last WeekSaturday, June 18, 2011
I LOVE hacking                             old codeSaturday, June 18, 2011
TechniquesSaturday, June 18, 2011
Techniques                            Universal                             Testing                            ExtendingSa...
UniversalSaturday, June 18, 2011
Liskov substitution                               principleSaturday, June 18, 2011
A subclass can be                          used in place of its                             superclassSaturday, June 18, 2...
Object                          Animal                          PersonSaturday, June 18, 2011
class Animal                end                class Person < Animal                endSaturday, June 18, 2011
def leg_count(animal)                  animal.legs                end                def account_number(person)           ...
Single Responsibility                       PrincipalSaturday, June 18, 2011
Each class has one                            and only one                            responsibilitySaturday, June 18, 2011
Each class has one                           reason to changeSaturday, June 18, 2011
Method ExtractionSaturday, June 18, 2011
class WebClient                  def get(url)                    url = URI.parse url                    Net::HTTP.get(url....
class WebClient                  def get(url)                    url = URI.parse url                    http_get          ...
I dont like it, but                                         it helps us to                class WebClient          reason ...
Object#extendSaturday, June 18, 2011
class Foo                  def metaclass                    class << self; self; end                  end                e...
[Foo, Object, Kernel, BasicObject]                [#<Module:0x81c98>, Foo, Object, Kernel, BasicObject]Saturday, June 18, ...
Code SeamsSaturday, June 18, 2011
TestingSaturday, June 18, 2011
Load Path HackingSaturday, June 18, 2011
$LOAD_PATHSaturday, June 18, 2011
ruby -Ifoo script.rbSaturday, June 18, 2011
require net/http                class WebClient                  def get(url)                    url = URI.parse url      ...
[aaron@higgins project (master)]$ find .                .                ./test                ./test/lib                ....
test/lib/net/http.rb     module Net       class HTTP         def self.get(host, path)           "hello world"         end ...
ruby -I test/lib web.rbSaturday, June 18, 2011
require web                require minitest/autorun                class WebTest < MiniTest::Unit::TestCase               ...
RSpec and             People dont know about -I     test/unit will                                            set your -I ...
Heavy HandedSaturday, June 18, 2011
Good for Small APIsSaturday, June 18, 2011
Constant HackingSaturday, June 18, 2011
require net/http                class WebClient                  def get(url)                    url = URI.parse url      ...
class MyHTTP                  def self.get(host, path)                    "hello world"                  end              ...
class WebTest < MiniTest::Unit::TestCase             def setup               WebClient.const_set(:Net, Module.new)        ...
class WebClient                  def get(url)                    url = URI.parse url                    ::Net::HTTP.get(ur...
Localized                          Still must    changes to                          mock          one class              ...
Subclass TestingSaturday, June 18, 2011
class WebClient                  def get(url)                    url = URI.parse url                    Net::HTTP.get(url....
require net/http                class WebClient                  def get(url)                    url = URI.parse url      ...
Class.newSaturday, June 18, 2011
class WebTest < MiniTest::Unit::TestCase             def test_get               client   = Class.new(WebClient) {         ...
Annoying                          ConstructorsSaturday, June 18, 2011
Many                                                                 parameters,                class Column              ...
Just Pass nilSaturday, June 18, 2011
def test_type_cast_true                  c = Column.new(nil, 1, int)                  assert_equal t, @conn.type_cast(true...
Cant construct,                                       but want to                                       break             ...
Too hard to                                                construct                pool = ActiveRecord::Base.connection_p...
pool = ActiveRecord::Base.connection_pool.dup                pool.extend(Module.new {                   def checkin conn  ...
Detecting ChangesSaturday, June 18, 2011
Measure http_get     class WebClient       def get(url)         url = URI.parse url         http_get(url.host, url.path)  ...
via Class.newSaturday, June 18, 2011
def test_http_get_count                  call_count = 0                  client = Class.new(WebClient) {                  ...
def test_http_get_count                  call_count = 0                  client = Class.new(WebClient) {                  ...
Decide to call                def test_http_get_count          super or not                  call_count = 0               ...
via Module.newSaturday, June 18, 2011
def test_http_get_count                  client = WebClient.new                      call_count = 0                      c...
def test_http_get_count                  client = WebClient.new                      call_count = 0                      c...
def test_http_get_count                  client = WebClient.new                      call_count = 0                      c...
ExtendingSaturday, June 18, 2011
Huge Methods!Saturday, June 18, 2011
def table_rows                  rows[table_name] = fixtures.map do |label, fixture|                     if model_class && ...
Extract MethodsSaturday, June 18, 2011
def belongs_to_row(association, row)                  # Do not replace association name with association foreign key if   ...
def habtm_row(association, row)                  if (targets = row.delete(association.name.to_s))                    targe...
def table_rows                  rows[table_name] = fixtures.map do |label, fixture|                    row = fixture.to_ha...
Extract ObjectSaturday, June 18, 2011
class RowFilter                  def rows                    fixtures.map do |label, fixture|                      row = f...
class RowFilter                  attr_reader :fixtures, :model_class                  def initialize(fixtures, model_class...
def table_rows                  filter = RowFilter.new(fixtures, model_class)                  rows[table_name] = filter.r...
Huge Classes!Saturday, June 18, 2011
Look at Method                              NamesSaturday, June 18, 2011
Look at shared                          instance variablesSaturday, June 18, 2011
Group Similar                            MethodsSaturday, June 18, 2011
Use SRP to create a                       new classSaturday, June 18, 2011
Then Delegate.Saturday, June 18, 2011
All API callsSaturday, June 18, 2011
Once we had                                           extracted the HTTP                class WebClient            methods...
class WebClient                  def initialize(client = Net::HTTP)                    @client = client                  e...
class TestHTTP < Struct.new(:data)                  def get(host, path)                    data[[host, path]]             ...
class WebTest < Test::Unit::TestCase                  def test_get_home                    mockhttp = TestHTTP.new({      ...
We define                          expectationsSaturday, June 18, 2011
Not Bound to HTTPSaturday, June 18, 2011
Legacy code can                            make you crySaturday, June 18, 2011
But it doesnt have toSaturday, June 18, 2011
Dont be afraid!Saturday, June 18, 2011
Ruby is your                 mocking frameworkSaturday, June 18, 2011
Credits & More InfoSaturday, June 18, 2011
Open Questions?Saturday, June 18, 2011
Do you like                  mocking / stubbing?Saturday, June 18, 2011
How do these testing                 tools impact your API?Saturday, June 18, 2011
Do you like hearts?Saturday, June 18, 2011
How about kittens?Saturday, June 18, 2011
<3 <3 <3Saturday, June 18, 2011
Upcoming SlideShare
Loading in...5
×

Nordic Ruby 2011

3,282

Published on

Published in: Technology
1 Comment
3 Likes
Statistics
Notes
No Downloads
Views
Total Views
3,282
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
17
Comments
1
Likes
3
Embeds 0
No embeds

No notes for slide

Nordic Ruby 2011

  1. 1. Saturday, June 18, 2011
  2. 2. Saturday, June 18, 2011
  3. 3. bitcoin == con-currency?Saturday, June 18, 2011
  4. 4. Saturday, June 18, 2011
  5. 5. José! Me!Saturday, June 18, 2011
  6. 6. WWFMD?Saturday, June 18, 2011
  7. 7. Public Service AnnouncementsSaturday, June 18, 2011
  8. 8. SIGSEGV is badSaturday, June 18, 2011
  9. 9. neversaydieSaturday, June 18, 2011
  10. 10. begin # something dangerous rescue NeverSayDie # fix memory endSaturday, June 18, 2011
  11. 11. "Not working in production mode"Saturday, June 18, 2011
  12. 12. DO NOT USE THIS SOFTWARESaturday, June 18, 2011
  13. 13. ruby -wSaturday, June 18, 2011
  14. 14. def hello x = Object.new # warning 10 + 10 endSaturday, June 18, 2011
  15. 15. warning: assigned but unused variable - xSaturday, June 18, 2011
  16. 16. How deprecation notices SHOULD be writtenSaturday, June 18, 2011
  17. 17. class Foo def deprecated if $VERBOSE warn "hey bro, dont call this" end 10 end endSaturday, June 18, 2011
  18. 18. RSpec ProblemSaturday, June 18, 2011
  19. 19. warning: useless use of == in void contextSaturday, June 18, 2011
  20. 20. it "passes" do 10.should == 10 11.should == 11 endSaturday, June 18, 2011
  21. 21. def check(thing) end def deprecated check 10.should == 10 check 11.should == 10 endSaturday, June 18, 2011
  22. 22. @tenderloveSaturday, June 18, 2011
  23. 23. AT&T, AT&T logo and all AT&T related marks are trademarks of AT&T Intellectual Property and/or AT&T affiliated companies.Saturday, June 18, 2011
  24. 24. Ruby Core TeamSaturday, June 18, 2011
  25. 25. Rails Core TeamSaturday, June 18, 2011
  26. 26. Saturday, June 18, 2011
  27. 27. White GuySaturday, June 18, 2011
  28. 28. Story about Geethika and pinochle, java, etcSaturday, June 18, 2011
  29. 29. Story about Geethika and pinochle, java, etc Its TYRA!Saturday, June 18, 2011
  30. 30. <3 <3 <3Saturday, June 18, 2011
  31. 31. "Congratulations, you just made us not consider Rails for anything anymore despite our coders liking it."Saturday, June 18, 2011
  32. 32. SWEDEN!Saturday, June 18, 2011
  33. 33. IKEA!Saturday, June 18, 2011
  34. 34. MEATBALLS!Saturday, June 18, 2011
  35. 35. SWEDISH FISH!Saturday, June 18, 2011
  36. 36. Made in Canada!Saturday, June 18, 2011
  37. 37. Made in Canada!Saturday, June 18, 2011
  38. 38. How do you catch such tiny fish?Saturday, June 18, 2011
  39. 39. Will you share your Swedish Fish Fishing spot?Saturday, June 18, 2011
  40. 40. Talk about Rails, Talk about work projects Mountain Dew and my Trail of TearsSaturday, June 18, 2011
  41. 41. Legacy CodeSaturday, June 18, 2011
  42. 42. What is Legacy Code?Saturday, June 18, 2011
  43. 43. UntestedSaturday, June 18, 2011
  44. 44. OldSaturday, June 18, 2011
  45. 45. Maintainers are gone Not UnderstoodSaturday, June 18, 2011
  46. 46. Importance of Legacy CodeSaturday, June 18, 2011
  47. 47. Old code contains KnowledgeSaturday, June 18, 2011
  48. 48. Solves Todays ProblemsSaturday, June 18, 2011
  49. 49. All Legacy Code is Not EqualSaturday, June 18, 2011
  50. 50. Tenderlove Tear FormulaSaturday, June 18, 2011
  51. 51. Code Burden Tears TimeSaturday, June 18, 2011
  52. 52. Tears cried at time TSaturday, June 18, 2011
  53. 53. Volume at time TSaturday, June 18, 2011
  54. 54. Last WeekSaturday, June 18, 2011
  55. 55. I LOVE hacking old codeSaturday, June 18, 2011
  56. 56. TechniquesSaturday, June 18, 2011
  57. 57. Techniques Universal Testing ExtendingSaturday, June 18, 2011
  58. 58. UniversalSaturday, June 18, 2011
  59. 59. Liskov substitution principleSaturday, June 18, 2011
  60. 60. A subclass can be used in place of its superclassSaturday, June 18, 2011
  61. 61. Object Animal PersonSaturday, June 18, 2011
  62. 62. class Animal end class Person < Animal endSaturday, June 18, 2011
  63. 63. def leg_count(animal) animal.legs end def account_number(person) person.account_number endSaturday, June 18, 2011
  64. 64. Single Responsibility PrincipalSaturday, June 18, 2011
  65. 65. Each class has one and only one responsibilitySaturday, June 18, 2011
  66. 66. Each class has one reason to changeSaturday, June 18, 2011
  67. 67. Method ExtractionSaturday, June 18, 2011
  68. 68. class WebClient def get(url) url = URI.parse url Net::HTTP.get(url.host, url.path) end endSaturday, June 18, 2011
  69. 69. class WebClient def get(url) url = URI.parse url http_get end private def http_get Net::HTTP.get(url.host, url.path) end endSaturday, June 18, 2011
  70. 70. I dont like it, but it helps us to class WebClient reason def get(url) url = URI.parse url http_get(url.host, url.path) end private def http_get(host, path) Net::HTTP.get(host, path) end endSaturday, June 18, 2011
  71. 71. Object#extendSaturday, June 18, 2011
  72. 72. class Foo def metaclass class << self; self; end end end x = Foo.new p x.metaclass.ancestors x.extend(Module.new { }) p x.metaclass.ancestorsSaturday, June 18, 2011
  73. 73. [Foo, Object, Kernel, BasicObject] [#<Module:0x81c98>, Foo, Object, Kernel, BasicObject]Saturday, June 18, 2011
  74. 74. Code SeamsSaturday, June 18, 2011
  75. 75. TestingSaturday, June 18, 2011
  76. 76. Load Path HackingSaturday, June 18, 2011
  77. 77. $LOAD_PATHSaturday, June 18, 2011
  78. 78. ruby -Ifoo script.rbSaturday, June 18, 2011
  79. 79. require net/http class WebClient def get(url) url = URI.parse url Net::HTTP.get(url.host, url.path) end endSaturday, June 18, 2011
  80. 80. [aaron@higgins project (master)]$ find . . ./test ./test/lib ./test/lib/net ./test/lib/net/http.rb ./web.rbSaturday, June 18, 2011
  81. 81. test/lib/net/http.rb module Net class HTTP def self.get(host, path) "hello world" end end endSaturday, June 18, 2011
  82. 82. ruby -I test/lib web.rbSaturday, June 18, 2011
  83. 83. require web require minitest/autorun class WebTest < MiniTest::Unit::TestCase def test_get client = WebClient.new response = client.get http://www.reddit.com/r/ruby assert_equal hello world, response end endSaturday, June 18, 2011
  84. 84. RSpec and People dont know about -I test/unit will set your -I for you require File.expand_path( File.join(.., foo))Saturday, June 18, 2011
  85. 85. Heavy HandedSaturday, June 18, 2011
  86. 86. Good for Small APIsSaturday, June 18, 2011
  87. 87. Constant HackingSaturday, June 18, 2011
  88. 88. require net/http class WebClient def get(url) url = URI.parse url Net::HTTP.get(url.host, url.path) end endSaturday, June 18, 2011
  89. 89. class MyHTTP def self.get(host, path) "hello world" end end WebClient.const_set(:Net, Module.new) WebClient::Net.const_set(:HTTP, MyHTTP)Saturday, June 18, 2011
  90. 90. class WebTest < MiniTest::Unit::TestCase def setup WebClient.const_set(:Net, Module.new) WebClient::Net.const_set(:HTTP, MyHTTP) end def teardown WebClient.send(:remove_const, :Net) end def test_get client = WebClient.new response = client.get http://www.reddit.com/r/ruby assert_equal hello world, response end endSaturday, June 18, 2011
  91. 91. class WebClient def get(url) url = URI.parse url ::Net::HTTP.get(url.host, url.path) end endSaturday, June 18, 2011
  92. 92. Localized Still must changes to mock one class entire API Heavy HandedSaturday, June 18, 2011
  93. 93. Subclass TestingSaturday, June 18, 2011
  94. 94. class WebClient def get(url) url = URI.parse url Net::HTTP.get(url.host, url.path) end endSaturday, June 18, 2011
  95. 95. require net/http class WebClient def get(url) url = URI.parse url http_get(url.host, url.path) end private def http_get(host, path) Net::HTTP.get(host, path) end endSaturday, June 18, 2011
  96. 96. Class.newSaturday, June 18, 2011
  97. 97. class WebTest < MiniTest::Unit::TestCase def test_get client = Class.new(WebClient) { def http_get(host, path) hello world end }.new response = client.get http://www.reddit.com/r/ruby assert_equal hello world, response end endSaturday, June 18, 2011
  98. 98. Annoying ConstructorsSaturday, June 18, 2011
  99. 99. Many parameters, class Column def initialize(name, default, sql_type = nil,dont care=about null true) some of them @name = name @sql_type = sql_type @null = null @limit = extract_limit(sql_type) @precision = extract_precision(sql_type) @scale = extract_scale(sql_type) @type = simplified_type(sql_type) @default = extract_default(default) @primary = nil @coder = nil end .... endSaturday, June 18, 2011
  100. 100. Just Pass nilSaturday, June 18, 2011
  101. 101. def test_type_cast_true c = Column.new(nil, 1, int) assert_equal t, @conn.type_cast(true, nil) assert_equal 1, @conn.type_cast(true, c) endSaturday, June 18, 2011
  102. 102. Cant construct, but want to break dependencies Not ConstructibleSaturday, June 18, 2011
  103. 103. Too hard to construct pool = ActiveRecord::Base.connection_poolSaturday, June 18, 2011
  104. 104. pool = ActiveRecord::Base.connection_pool.dup pool.extend(Module.new { def checkin conn @checkins << conn conn.object_id end })Saturday, June 18, 2011
  105. 105. Detecting ChangesSaturday, June 18, 2011
  106. 106. Measure http_get class WebClient def get(url) url = URI.parse url http_get(url.host, url.path) end private def http_get(host, path) Net::HTTP.get(host, path) end endSaturday, June 18, 2011
  107. 107. via Class.newSaturday, June 18, 2011
  108. 108. def test_http_get_count call_count = 0 client = Class.new(WebClient) { define_method(:http_get) { |host, path| call_count += 1 "hello world" } }.new assert_equal 0, call_count client.get http://www.reddit.com/r/ruby assert_equal 1, call_count endSaturday, June 18, 2011
  109. 109. def test_http_get_count call_count = 0 client = Class.new(WebClient) { define_method(:http_get) { |host, path| call_count += 1 "hello world" } }.new assert_equal 0, call_count client.get http://www.reddit.com/r/ruby assert_equal 1, call_count endSaturday, June 18, 2011
  110. 110. Decide to call def test_http_get_count super or not call_count = 0 client = Class.new(WebClient) { define_method(:http_get) { |host, path| call_count += 1 "hello world" } }.new assert_equal 0, call_count client.get http://www.reddit.com/r/ruby assert_equal 1, call_count endSaturday, June 18, 2011
  111. 111. via Module.newSaturday, June 18, 2011
  112. 112. def test_http_get_count client = WebClient.new call_count = 0 client.extend(Module.new { define_method(:http_get) { |host, path| call_count += 1 "hello world" } }) assert_equal 0, call_count client.get http://www.reddit.com/r/ruby assert_equal 1, call_count endSaturday, June 18, 2011
  113. 113. def test_http_get_count client = WebClient.new call_count = 0 client.extend(Module.new { define_method(:http_get) { |host, path| call_count += 1 "hello world" } }) assert_equal 0, call_count client.get http://www.reddit.com/r/ruby assert_equal 1, call_count endSaturday, June 18, 2011
  114. 114. def test_http_get_count client = WebClient.new call_count = 0 client.extend(Module.new { define_method(:http_get) { |host, path| call_count += 1 "hello world" } }) assert_equal 0, call_count client.get http://www.reddit.com/r/ruby assert_equal 1, call_count endSaturday, June 18, 2011
  115. 115. ExtendingSaturday, June 18, 2011
  116. 116. Huge Methods!Saturday, June 18, 2011
  117. 117. def table_rows rows[table_name] = fixtures.map do |label, fixture| if model_class && model_class < ActiveRecord::Base reflection_class.reflect_on_all_associations.each do |association| case association.macro when :belongs_to # Do not replace association name with association foreign key if they are named the same fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s if association.name.to_s != fk_name && value = row.delete(association.name.to_s) if association.options[:polymorphic] && value.sub!(/s*(([^)]*))s*$/, "") # support polymorphic belongs_to as "label (Type)" row[association.foreign_type] = $1 end row[fk_name] = ActiveRecord::Fixtures.identify(value) end when :has_and_belongs_to_many if (targets = row.delete(association.name.to_s)) targets = targets.is_a?(Array) ? targets : targets.split(/s*,s*/) table_name = association.options[:join_table] rows[table_name].concat targets.map { |target| { association.foreign_key => row[primary_key_name], association.association_foreign_key => ActiveRecord::Fixtures.identify (target) } } end end end end row end rows endSaturday, June 18, 2011
  118. 118. Extract MethodsSaturday, June 18, 2011
  119. 119. def belongs_to_row(association, row) # Do not replace association name with association foreign key if they are named the same fk_name = (association.options[:foreign_key] || "# {association.name}_id").to_s if association.name.to_s != fk_name && value = row.delete (association.name.to_s) if association.options[:polymorphic] && value.sub!(/s*(([^)] *))s*$/, "") # support polymorphic belongs_to as "label (Type)" row[association.foreign_type] = $1 end row[fk_name] = ActiveRecord::Fixtures.identify(value) endSaturday, June 18, 2011
  120. 120. def habtm_row(association, row) if (targets = row.delete(association.name.to_s)) targets = targets.is_a?(Array) ? targets : targets.split(/s*, s*/) table_name = association.options[:join_table] rows[table_name].concat targets.map { |target| { association.foreign_key => row [primary_key_name], association.association_foreign_key => ActiveRecord::Fixtures.identify(target) } } end endSaturday, June 18, 2011
  121. 121. def table_rows rows[table_name] = fixtures.map do |label, fixture| row = fixture.to_hash if model_class && model_class < ActiveRecord::Base # If STI is used, find the correct subclass for association reflection reflection_class = if row.include?(inheritance_column_name) row[inheritance_column_name].constantize rescue model_class else model_class end reflection_class.reflect_on_all_associations.each do |association| case association.macro when :belongs_to belongs_to_row(association, row) when :has_and_belongs_to_many habtm_row(association, row) end end end row end rows endSaturday, June 18, 2011
  122. 122. Extract ObjectSaturday, June 18, 2011
  123. 123. class RowFilter def rows fixtures.map do |label, fixture| row = fixture.to_hash if model_class && model_class < ActiveRecord::Base # If STI is used, find the correct subclass for association reflection reflection_class = if row.include?(inheritance_column_name) row[inheritance_column_name].constantize rescue model_class else model_class end reflection_class.reflect_on_all_associations.each do |association| case association.macro when :belongs_to belongs_to_row(association, row) when :has_and_belongs_to_many habtm_row(association, row) end end end row end end endSaturday, June 18, 2011
  124. 124. class RowFilter attr_reader :fixtures, :model_class def initialize(fixtures, model_class) @fixtures = fixtures @model_class = model_class end endSaturday, June 18, 2011
  125. 125. def table_rows filter = RowFilter.new(fixtures, model_class) rows[table_name] = filter.rows rows endSaturday, June 18, 2011
  126. 126. Huge Classes!Saturday, June 18, 2011
  127. 127. Look at Method NamesSaturday, June 18, 2011
  128. 128. Look at shared instance variablesSaturday, June 18, 2011
  129. 129. Group Similar MethodsSaturday, June 18, 2011
  130. 130. Use SRP to create a new classSaturday, June 18, 2011
  131. 131. Then Delegate.Saturday, June 18, 2011
  132. 132. All API callsSaturday, June 18, 2011
  133. 133. Once we had extracted the HTTP class WebClient methods to their own functions, could def get(url) reason about HTTP url = URI.parse url api. http_get(url.host, url.path) end private def http_get(host, path) Net::HTTP.get(host, path) end endSaturday, June 18, 2011
  134. 134. class WebClient def initialize(client = Net::HTTP) @client = client end def get(url) url = URI.parse url http_get(url.host, url.path) end private def http_get(host, path) @client.get(host, path) end endSaturday, June 18, 2011
  135. 135. class TestHTTP < Struct.new(:data) def get(host, path) data[[host, path]] end endSaturday, June 18, 2011
  136. 136. class WebTest < Test::Unit::TestCase def test_get_home mockhttp = TestHTTP.new({ [localhost, /~aaron/] => hello }) wc = WebClient.new mockhttp assert_equal hello, wc.get(http://localhost/~aaron/) end endSaturday, June 18, 2011
  137. 137. We define expectationsSaturday, June 18, 2011
  138. 138. Not Bound to HTTPSaturday, June 18, 2011
  139. 139. Legacy code can make you crySaturday, June 18, 2011
  140. 140. But it doesnt have toSaturday, June 18, 2011
  141. 141. Dont be afraid!Saturday, June 18, 2011
  142. 142. Ruby is your mocking frameworkSaturday, June 18, 2011
  143. 143. Credits & More InfoSaturday, June 18, 2011
  144. 144. Open Questions?Saturday, June 18, 2011
  145. 145. Do you like mocking / stubbing?Saturday, June 18, 2011
  146. 146. How do these testing tools impact your API?Saturday, June 18, 2011
  147. 147. Do you like hearts?Saturday, June 18, 2011
  148. 148. How about kittens?Saturday, June 18, 2011
  149. 149. <3 <3 <3Saturday, June 18, 2011
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×