I am trying to create the game Mastermind using test-driven development. I am having issues figuring out how to pass this specific test:
it "should valiate secret contains four accepted uppercase characters" do
#game.secret = "XXXX"
secret = "RRRR"
valid1 = #game.checksecret(secret)
valid2 = check_valid(secret)
valid1.should == valid2 && #game.secret.should == secret && valid1.should == 0
end
This is the code I have at the moment:
def checksecret(secret)
secret = "RRRR"
valid1 = secret
valid2 = check_valid(secret)
valid1.should == valid2 && secret.should == secret && valid1.should == 0
end
This is the error message I get.
1) OXs_Game::Game#Mastermind game should valiate secret contains four accepted uppercase characters
Failure/Error: #game.secret = secret
NoMethodError:
undefined method `secret=' for nil:NilClass
# ./wad_mastermind_spec_01.rb:13:in `check_valid'
# ./wad_mastermind_gen_01.rb:61:in `checksecret'
# ./wad_mastermind_spec_01.rb:92:in `block (3 levels) in <module:OXs_Game>'
I feel like I am trying to solve it the wrong way but can't figure out how I should be solving the problem.
Related
ZAP automation :undefined method `[]' for nil:NilClass (NoMethodError)
I am getting the above error while trying to get the response of zap using ruby. below is my code:
Then(/^I should be able to see security warnings$/) do
#Get response from via RestClient framework method.
begin
response = JSON.parse RestClient.get "http://#{$zap_proxy}:#{$zap_proxy_port}/json/core/view/alerts"
rescue RestClient::ServerBrokeConnection
#Classify the alerts
events = response['alerts']
high_risks = events.select{|x| x['risk'] == 'High'}
high_count = high_risks.size
medium_count = events.select{|x| x['risk'] == 'Medium'}.size
low_count = events.select{|x| x['risk'] == 'Low'}.size
informational_count = events.select{|x| x['risk'] == 'Informational'}.size
end
#Check high alert count and print them
if high_count > 0
high_risks.each { |x| p x['alert'] }
end
#Expect high alert count equal to 0
expect(high_count).to eq 0
#Print alerts with risk levels
site = Capybara.app_host
response = JSON.parse RestClient.get "http://#{$zap_proxy}:#{$zap_proxy_port}/json/core/view/alerts",
params: { zapapiformat: 'JSON', baseurl: site }
response['alerts'].each { |x| p "#{x['alert']} risk level: #{x['risk']}"}
end
some one please help me. my intention is to print the security alerts and display them on my command prompt
I think you have nil value in events and you try to get value x['...'] from nil .
it would take a little more detail including the line.
edit:
try events = response['alerts'].reject { |x| x.nil? }
I am building a Tic Tac Toe game in which the user can play a computer, or computers can play each other. While building the AI I am running into the below error. How can I debug this? I understand it is to do with a loop somewhere but I can't find it.
ttt-with-ai-project-cb-000/lib/players/computer.rb:13:in `each': stack level too deep (SystemStackError)
from ttt-with-ai-project-cb-000/lib/players/computer.rb:13:in `detect'
from ttt-with-ai-project-cb-000/lib/players/computer.rb:13:in `check_move'
from ttt-with-ai-project-cb-000/lib/players/computer.rb:8:in `move'
from ttt-with-ai-project-cb-000/lib/game.rb:61:in `wargame_turn'
from ttt-with-ai-project-cb-000/lib/game.rb:64:in `wargame_turn'
from ttt-with-ai-project-cb-000/lib/game.rb:64:in `wargame_turn'
from ttt-with-ai-project-cb-000/lib/game.rb:64:in `wargame_turn'
from ttt-with-ai-project-cb-000/lib/game.rb:64:in `wargame_turn'
... 11900 levels...
from bin/tictactoe:37:in `block in run_game'
from bin/tictactoe:35:in `times'
from bin/tictactoe:35:in `run_game'
from bin/tictactoe:79:in `<main>'
The Offending Methods
lib/players/computer.rb
def move(board)
check_move(board)
end
def check_move(board)
win_combo = Game::WIN_COMBINATIONS.detect do |indices|
board.cells[indices[0]] == token && board.cells[indices[1]] == token || board.cells[indices[1]] == token && board.cells[indices[2]] == token || board.cells[indices[0]] == token && board.cells[indices[2]] == token
end
win_combo.detect {|index| board.cells[index] == " "}.join if win_combo
end
lib/game.rb
def wargame_turn
input = current_player.move(board)
if !board.valid_move?(input)
wargame_turn
else
board.update(input, current_player)
end
end
bin/tictactoe calls the method in the following block within #run_game:
100.times do
game = Game.new(Players::Computer.new("X"), player_2 = Players::Computer.new("O"))
game.wargames
if game.winner == "X"
x_wins += 1
elsif game.winner == "O"
x_wins += 1
elsif game.draw?
draws += 1
end
end
You can use the ruby Tracer class:
ruby -r tracer your_main_script.rb
Also, you can take a look at your code and see where the loop may happen:
def wargame_turn
input = current_player.move(board)
if !board.valid_move?(input)
wargame_turn #### HERE'S A POTENTIAL INFINITE LOOP
So the heart of the problem seems at:
if !board.valid_move?(input)
It could be a good start.
I'm new to Ruby and in various open source software I've noticed a number of "statements" in some RSpec descriptions that appear not to accomplish what they intended, like they wanted to make an assertion, but didn't. Are these coding errors or is there some RSpec or Ruby magic I'm missing? (Likelihood of weirdly overloaded operators?)
The examples, with #??? added to the suspect lines:
(rubinius/spec/ruby/core/array/permutation_spec.rb)
it "returns no permutations when the given length has no permutations" do
#numbers.permutation(9).entries.size == 0 #???
#numbers.permutation(9) { |n| #yielded << n }
#yielded.should == []
end
(discourse/spec/models/topic_link_spec.rb)
it 'works' do
# ensure other_topic has a post
post
url = "http://#{test_uri.host}/t/#{other_topic.slug}/#{other_topic.id}"
topic.posts.create(user: user, raw: 'initial post')
linked_post = topic.posts.create(user: user, raw: "Link to another topic: #{url}")
TopicLink.extract_from(linked_post)
link = topic.topic_links.first
expect(link).to be_present
expect(link).to be_internal
expect(link.url).to eq(url)
expect(link.domain).to eq(test_uri.host)
link.link_topic_id == other_topic.id #???
expect(link).not_to be_reflection
...
(chef/spec/unit/chef_fs/parallelizer.rb)
context "With :ordered => false (unordered output)" do
it "An empty input produces an empty output" do
parallelize([], :ordered => false) do
sleep 10
end.to_a == [] #???
expect(elapsed_time).to be < 0.1
end
(bosh/spec/external/aws_bootstrap_spec.rb)
it "configures ELBs" do
load_balancer = elb.load_balancers.detect { |lb| lb.name == "cfrouter" }
expect(load_balancer).not_to be_nil
expect(load_balancer.subnets.sort {|s1, s2| s1.id <=> s2.id }).to eq([cf_elb1_subnet, cf_elb2_subnet].sort {|s1, s2| s1.id <=> s2.id })
expect(load_balancer.security_groups.map(&:name)).to eq(["web"])
config = Bosh::AwsCliPlugin::AwsConfig.new(aws_configuration_template)
hosted_zone = route53.hosted_zones.detect { |zone| zone.name == "#{config.vpc_generated_domain}." }
record_set = hosted_zone.resource_record_sets["\\052.#{config.vpc_generated_domain}.", 'CNAME'] # E.g. "*.midway.cf-app.com."
expect(record_set).not_to be_nil
record_set.resource_records.first[:value] == load_balancer.dns_name #???
expect(record_set.ttl).to eq(60)
end
I don't think there is any special behavior. I think you've found errors in the test code.
This doesn't work because there's no assertion, only a comparison:
#numbers.permutation(9).entries.size == 0
It would need to be written as:
#numbers.permutation(9).entries.size.should == 0
Or using the newer RSpec syntax:
expect(#numbers.permutation(9).entries.size).to eq(0)
Hi I have a string passed back from rspec.
It should show
"alias/public_html/ab1/ab2/"
but I am getting "\"alias/public_html/ab1/ab2/\""
I am getting the rspec error below:
WebServer::HttpdConf#alias_path returns the aliased path
Failure/Error: expect(httpd_file.alias_path('/ab/')).to eq 'alias/public_html/ab1/ab2/'
expected: "alias/public_html/ab1/ab2/"
got: "\"alias/public_html/ab1/ab2/\""
(compared using ==)
# ./spec/lib/config/httpd_conf_spec.rb:90:in `(root)'
And here is my actual program file
def alias_path(path)
#hash_httpd['Alias'][path]
end
Please help
EDIT
Sorry, I am new to RUby, here is the httpd_file
def initialize(httpd_file_content)
#hash_httpd = Hash.new
httpd_file_content.each_line do | line |
#commands = line.split
if #commands.length == 2
#hash_httpd[#commands[0]] = #commands[1]
else
if !#hash_httpd.has_key?(#commands[0])
al = Hash.new
#hash_httpd[#commands[0]] = al
else
al = #hash_httpd[#commands[0]]
end
al[#commands[1]] = #commands[2]
end
end
end
If you are sure that your alias_path output will be "alias/public_html/ab1/ab2/", then you can just modify your alias_path method definition by removing the quotes (if any) from the returned path:
def alias_path(path)
#hash_httpd['Alias'][path].gsub('"', '')
end
I am trying to write a method called square_digits that squares every digit in a given number. I wrote:
def square_digits(num)
number_array = num.to_s.split("")
num_to_int = number_array.to_i
num_squared = num_to_int.each{|n| n**2}
return num_squared.join("")
end
When trying to run square_digits(3212), which should return 9414, I get the following error message:
`block in square_digits': undefined method `**' for "3":String (NoMethodError)
from `each'
from `square_digits'
from `
'
I'm not quite sure what I should do to fix it; any suggestions?
Hmm there are a few problems here:
With the input 123 it should error on:
num_to_int = number_array.to_i
With:
NoMethodError: undefined method 'to_i' for ["1","2","3"]:Array
You want:
num_to_int = number_array.map(&:to_i)
Also
num_squared = num_to_int.each{|n| n**2}
doesn't return the results of each just the original array.
So with the first fix it will just return "123"
you want:
num_squared = num_to_int.map{|n| n**2}
So the final function looks like:
def square_digits(num)
number_array = num.to_s.split("")
num_to_int = number_array.map(&:to_i)
num_squared = num_to_int.map{|n| n**2}
return num_squared.join("")
end
Although i'm confused about what you are trying to achieve.
You can also try this ;)
def square_digits(num)
num.to_s.split('').map { |n| n.to_i ** 2 }.join("")
end
Or
def square_digits(num)
num.to_s.chars.map { |n| n.to_i ** 2 }.join("")
end