Skip to main content
  1. Posts/

Day 72

OldDays seitan-spin cucumber ruby

Assign tasks to future you.
Assign tasks to future you.

In which we achieve some limited closure.

Test Every Day
#

Rest when dead but not lawful, in a map with no karma res point, if not a thief
#

Is this really the last of the Underworld cases? Wonderful. Given what we already have, it’s pretty trivial to do:

features/config_file.feature
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
# Rest when dead but not lawful, in a map with no karma res point, if not a thief
Scenario: UnderworldEnabled True, neutral non-thief corpse goes there if no karma res point
	Given I use the "minimal" database
	And I set "UnderworldEnabled" in the config file to "True"
	And I remove the karma res point for map "0"
	And I add player and character "TestBadCorpse04"
	And I set the character's alignment to neutral
	And I set the character's current HP to "1"
	And I put poison berries in the the character's right hand
	And the server is started
	When I log on as "TestBadCorpse04"
	And I enter the game
    And I eat "berries"
	And within "10" turns I see the message "You are dead"
	And I rest
	Then I saw a message "The world dissolves around you."

Scenario: UnderworldEnabled False, neutral non-thief corpse doesn't go there if no karma res point
	Given I use the "minimal" database
	And I set "UnderworldEnabled" in the config file to "False"
	And I remove the karma res point for map "0"
	And I add player and character "TestBadCorpse04"
	And I set the character's alignment to neutral
	And I set the character's current HP to "1"
	And I put poison berries in the the character's right hand
	And the server is started
	When I log on as "TestBadCorpse04"
	And I enter the game
    And I eat "berries"
	And within "10" turns I see the message "You are dead"
	And I rest
	Then I did not see a message "The world dissolves around you."

I took the opportunity to refactor the alignment step a little, so it’s just one step that passes on the specific alignment as a symbol:

features/steps/character_steps.rb
93
94
95
Given(/^I set the character's alignment to (lawful|neutral|evil)$/) do |desired_alignment|
  set_character_alignment(get_player_id(@user[:char_name]), desired_alignment.to_sym)
end

and then I mirror the enum in the server code to push the appropriate value to the DB:

features/lib/db/player.rb
136
137
138
139
140
141
142
143
144
145
146
147
148
149
def set_character_alignment(player_id, desired_alignment)
  alignment_list = [ :none, :lawful, :neutral, :chaotic, :evil, :amoral, :all ]
  alignment_num = alignment_list.index(desired_alignment)
  debug_msg "Alignment #{desired_alignment} is number #{alignment_num}"
  fail "Unknown alignment" if alignment_num.nil?
  client = connect_to_db(@server_database)
  query = "UPDATE [#{@server_database}].[dbo].[Player] SET \
    alignment = #{alignment_num} \
    WHERE playerID = '#{player_id}'"
  debug_msg query
  result = client.execute(query)
  affected_rows = result.do
  fail "Unable to update player!" if 1 != affected_rows
end

The best way to do it? Not sure; further refactoring will definitely occur as we move toward testing two separate server implementations.

50 scenarios (50 passed)
430 steps (430 passed)
11m47.827s

Tackle a TODO every other day
#

Looking at the TODOs in the test repository, a lot of them have to do with hardcoded IDs. For example:

features/steps/character_steps.rb
 8
 9
10
11
Given(/^I put a spellbook in the the character's right hand$/) do
  # TODO - not hardcoded item ID
  put_attuned_in_player_hand(get_player_id(@user[:char_name]), 31000, :right)
end

This code only works for databases where the ID for a spellbook happens to be 31000, and gets poor marks for readability. Let’s add a very flexible item ID lookup method and use that:

features/steps/character_steps.rb
 8
 9
10
11
Given(/^I put a spellbook in the the character's right hand$/) do
  item_id = lookup_item_id({ name: 'spellbook' })
  put_attuned_in_player_hand(get_player_id(@user[:char_name]), item_id, :right)
end
features/lib/db/item.rb
30
31
32
33
34
35
36
37
38
39
def lookup_item_id(lookup_hash)
  client = connect_to_db(@server_database)
  query = db_field_from_hash('CatalogItem', lookup_hash, 'itemID')
  debug_msg "Query is #{query}"
  result = client.execute(query)
  row = result.each(:first => true)
  debug_msg row.inspect
  fail "Unable to get itemID!" if 1 != result.affected_rows
  row[0]['itemID']
end
features/lib/db/sql_misc.rb
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def db_field_from_hash(table_name, db_hash, return_field)
  where_clauses = []
  db_hash.keys.each do |key|
    if db_hash[key].is_a?(String)
      where_clauses << "#{key}='#{db_hash[key]}'"
    elsif db_hash[key].nil?
      where_clauses << "#{key}=NULL"
    else
      where_clauses << "#{key}=#{db_hash[key]}"
    end
  end
  query = "SELECT #{return_field} FROM [dbo].[#{table_name}] " +
          "WHERE #{where_clauses.join(' AND ')}" 
end

We’ll probably refactor this further once we have two different data storage mechanisms, but this will work for now.

Similar code removes a lot of the TODOs, and eventually:

Searching 31 files for "TODO"

0 matches

Added another test for fun
#

I even added a test while I was messing with the player effect code:

features/temp.feature
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Scenario: Multiple character effects stack correctly
	Given I use the "minimal" database
	And I add player and character "TestSubject01"
	And I inflict fear on the character for "2" turns
	And I blind the character for "4" turns
	And the server is started
	When I log on as "TestSubject01"
	And I enter the game
	Then I saw a message "You are scared!"
	And after "2" turns I no longer see the message "You are scared!"
	Then I saw a message "You are blind!"
	And after "2" turns I no longer see the message "You are blind!"

Simple, but forced me to learn:

  • the PlayerEffect slots are one-based, not zero-based (initially my first-applied effect was ignored).
  • the display of fear overrides the display of blindess (I’m tempted to call this a bug).

Now:

51 scenarios (51 passed)
441 steps (441 passed)
12m28.001s

And maybe we can add a bunch more player effect tests. Tomorrow.


Useful Stuff
#


More to come
More to come

Day 72 code - tests