I am working on decoding a Shopify Script (for cart discounts) that was written by another dev and it includes some Ruby syntax I haven't seen before. Pulling up a google search there was no explanation I've found behind the use of "^" in the code below, specifically in these lines:
return #invert ^ ((#tags & customer_tags).length > 0)
return #invert ^ ((#tags & customer_tags).length > 0)
See context below:
class CustomerTagQualifier < Qualifier
def initialize(match_type, match_condition, tags)
#match_condition = match_condition
#invert = match_type == :does_not
#tags = tags.map(&:downcase)
end
def match?(cart, selector = nil)
return true if cart.customer.nil? && #invert
return false if cart.customer.nil?
customer_tags = cart.customer.tags.to_a.map(&:downcase)
case #match_condition
when :match
return #invert ^ ((#tags & customer_tags).length > 0)
else
return #invert ^ partial_match(#match_condition, customer_tags, #tags)
end
end
end
Does anyone have any idea? Thanks for any input
This is a boolean XOR operator. https://en.wikipedia.org/wiki/Exclusive_or
Related
I've never used Ruby before, and am attempting to run a program written
long ago. I've installed Ruby 2.4.1 and the gem package [test-unit
3.4.3] OK, but when I try to run it, I get an error:
tcreporter.rb:156: formal argument cannot be a class variable
##tc_array.each do |##tc|
^
Is there something in particular I'm doing wrong?
Below is the code snippet :
class TCReporter
##m = nil; ##c = nil; ##tc = nil; ##status = 'p'; ##notes = nil; ##tlArr = []
##resultMapping = {'p'=>'PASS', 'f'=>'FAIL', 'b'=>'BLOCKED', 's'=>'SKIP','pr'=>'PREQFAIL', 'con'=>'CONERR', 'h'=>'HWSKIP', 'cor'=>'CORE'}
def self.report_result(currentTest, status, notes=nil)
if $trInit
##m = currentTest.split('(')[0] ###m is the test METHOD currently being executed in the framework.
##c = currentTest.split('(')[1].split(')')[0] ###c is the test CLASS currently being executed in the framework
if ##c =~ /(?:#{TESTRAIL_TEST_PREFIXES.join('|')})_\d*$/i #If there's a mapping on the test class then report a test class result.
##tc = ##c.scan(/(?:#{TESTRAIL_TEST_PREFIXES.join('|')})_\d*$/i)[0].upcase.sub('_', '-') #Get the TR class mapping
#When reporting at the test class level, the status always starts out as 'p' (PASS). If there's any
#non-passing status for any test method within the test class (blocked or failed) then use that result
#for reporting. Once the global status '##status' has been updated once then no more updating occurs.
if ##status == 'p' && status != 'p'
##status = status
##notes = notes
end
if eval("#{##c}.public_instance_methods.grep(/^test_/).sort.first") == ##m && eval("#{##c}.public_instance_methods.grep(/^test_/).sort.last") == ##m #The first test method is the last test method. All done, do a TestLink update.
begin
result = TR.report_tc_result(##tc, TESTRAIL_PROJECT, TESTRAIL_MILESTONE, TESTRAIL_PLAN, TESTRAIL_RUN, TESTRAIL_BUILD, ##status, (##notes ? ##notes : notes))
ensure
result.case_id = ##tc
result.class = ##c
result.method = ##m
if !result.success #success means a successful communication with testLink and test case was found and updated.
$trReport = ReportFile.new('tr_report.txt') if !$trReport
$trReport.puts "#{##tc}, #{TEST_ARGS.project}, #{TEST_ARGS.plan}, #{TEST_ARGS.build}, #{TEST_ARGS.platform}, #{##c}, #{##m}, #{status} 'class', #{result.message ||= result.exception}"
end
end
elsif eval("#{##c}.public_instance_methods.grep(/^test_/).sort.first") == ##m #A new test class is being evaluated. Set everything to default except status (use whatever the first test class returned).
##m = nil; ##c = nil; ##tc = nil; ##status = status
elsif eval("#{##c}.public_instance_methods.grep(/^test_/).sort.last") == ##m #Done with the test class. Time to report the test result.
begin
result = TR.report_tc_result(##tc, TESTRAIL_PROJECT, TESTRAIL_MILESTONE, TESTRAIL_PLAN, TESTRAIL_RUN, TESTRAIL_BUILD, ##status, (##notes ? ##notes : notes))
ensure
result.case_id = ##tc
result.class = ##c
result.method = ##m
if !result.success #success means a successful communication with testLink and test case was found and updated.
$trReport = ReportFile.new('tr_report.txt') if !$trReport
$trReport.puts "#{##tc}, #{TEST_ARGS.project}, #{"#{TEST_ARGS.milestone}, " if TEST_ARGS.milestone}#{TEST_ARGS.plan}, #{TEST_ARGS.build}, #{TEST_ARGS.platform}, #{##c}, #{##m}, #{status} 'class', #{result.message ||= result.exception}"
end
end
else #The test class is still being executed. Don't update TestLink yet, just check for a non-passing result.
if ##status == 'p' && status != 'p' #Update the test status if it's a non-pass result. Otherwise, use the earlier failed or blocked status.
##status = status
end
end
end
#If there's a mapping on a test method then report a test method result.
if ##m =~ /(?:#{TESTRAIL_TEST_PREFIXES.join('|')})_\d?[\d_]+$/i
##tc_array = ##m.scan(/(?:#{TESTRAIL_TEST_PREFIXES.join('|')})_\d?[\d_]+$/i)[0].upcase.sub('_', '-').split("_")
if ##tc_array.size > 1
tmp_prefix = ##tc_array[0].split("-").first
tmp_array = []
##tc_array.each do|tmp|
tmp_array << tmp_prefix + "-" + tmp.split("-").last
end
##tc_array = tmp_array
end
##tc_array.each do |##tc|
begin
result = TR.report_tc_result(##tc, TESTRAIL_PROJECT, TESTRAIL_MILESTONE, TESTRAIL_PLAN, TESTRAIL_RUN, TESTRAIL_BUILD, status, notes)
puts status
rescue => e
puts e
ensure
if result && !result.success
$trReport = ReportFile.new('tr_report.txt') if !$trReport
$trReport.puts "#{##tc}, #{TEST_ARGS.project}, #{"#{TEST_ARGS.milestone}, " if TEST_ARGS.milestone}#{TEST_ARGS.plan}, #{TEST_ARGS.build}, #{TEST_ARGS.platform}, #{##c}, #{##m}, #{status} 'class', #{result.message ||= result.exception}"
end
end
end
end
end
end
Thanks in advance
This is fixed now after making "tc" as local variable.
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)
Below is a method which should return true if there is an existing user (a test to happen before trying to drop user). But it is not returning anything. I
def is_user?(user_name)
puts "Checking if #{user_name} exists: "
select_sql = <<-EOF
SELECT COUNT(*)
FROM all_users
WHERE username = upper('#{user_name}')
EOF
select_stmt = #conn.create_statement
result_set = select_stmt.execute_query(select_sql)
count = Array.new
while(result_set.next)
count = result_set.getInt(1)
end
result_set.close()
select_stmt.close()
if (count > 0)
#puts "#{count}" <---- This prints 1
return true
else
return false
end
end
After creating the connection object, I am calling this method and it not returning anything. Connection has been established successfully. I tried to return count but it is also not returning anything. Can anyone help me find what is the problem?
Thanks.
Why not use:
(count > 0)
by itself instead of:
if (count > 0)
#puts "#{count}" <---- This prints 1
return true
else
return false
end
It does the same thing and would be idiomatic Ruby.
I'd also strongly recommend you use the Sequel ORM for your database connectivity needs. It's extremely well written and portable.
Once you'd established a connection to your database you could use this to replace your code:
def is_user?(user_name)
DB[:users].where(:username => user_name.upcase).count > 0
end
I need to show some treeview item text striked out text into a QT treeview from Ruby.
After some reading on QT documentation and much coding, I found that only when rendering font in bold, also the strikeout was rendered.
So I wonder, where I'm doing wrong?
This is the code to achive the result shown above. Note as I set strikeout for every even row item.
I'm using Ruby 1.8.7 and Qt 4.6.2 and qt4ruby 4.4.3-6 on Mandriva Linux.
require 'Qt4'
require 'date'
class MyStandardItem < Qt::StandardItem
def initialize(str = nil)
super str
end
def data(role = Qt::UserRole + 1)
return super(role) unless role == Qt::FontRole
ret_val = Qt::Font.new()
#parameters for "fromString":font family, pointSizeF, pixelSize, QFont::StyleHint, QFont::Weight, QFont::Style, underline, strikeOut, fixedPitch, rawMode
ret_val.fromString "sans serif,-1,-1,0,0,0,0,0,0,0"
case role
when Qt::FontRole
ret_val.setStrikeOut(true) if (index.row % 2) == 0
if index.column == 1
ret_val.weight = Qt::Font.Bold
else
ret_val.weight = Qt::Font.Normal
end
return Qt::Variant.fromValue(ret_val)
end
return ret_val
end
end
Qt::Application.new(ARGV) do
treeview = Qt::TreeView.new do
model = Qt::StandardItemModel.new self
head = [MyStandardItem.new "Qt v. #{Qt.version}"]
head << MyStandardItem.new("Ruby v. #{VERSION}")
head << MyStandardItem.new("Qt4Ruby v. 4.4.3-6 (Mandriva)")
model.append_row head
(1..10).each do |i|
col0 = MyStandardItem.new 'some text'
col0.check_state = ((i % 3) == 0)? Qt.Checked : Qt.Unchecked
col0.checkable = true
col0.editable= false
col1 = MyStandardItem.new "line ##{i}"
col2 = MyStandardItem.new((Date.today + i).strftime '%d/%m/%y')
model.append_row [col0, col1, col2]
end
self.model = model
show
end
exec
end
Eventually I find an hackish trick to overcome this problem. Playing around after reading again the enum QFont::Weight description I tried to set
ret_val.weight = 51 # Qt::Font.Normal value is 50
instead of
ret_val.weight = Qt::Font.Normal
and magically the normal text appears striked out!
Maybe this strange behaviour is due to a bug on QT?
I'm getting some weirdness with QtRuby when using a TableWidget. The table widget loads, but when you click on the elements in the row, the app segfaults and crashes.
require 'Qt4'
class SimpleModel < Qt::AbstractTableModel
def rowCount(parent)
return 1
end
def columnCount(parent)
return 1
end
def data(index, role=Qt::DisplayRole)
return Qt::Variant.new("Really Long String") if index.row == 0 and index.column == 0 and role == Qt::DisplayRole
return Qt::Variant.new
end
end
Qt::Application.new(ARGV) do
Qt::TableWidget.new(1, 1) do
set_model SimpleModel.new
show
end
exec
end
The backtrace seems to imply that it is bombing in mousePressEvent
#6 0x01624643 in QAbstractItemView::pressed(QModelIndex const&) () from /usr/lib/libQtGui.so.4
#7 0x016306f5 in QAbstractItemView::mousePressEvent(QMouseEvent*) () from /usr/lib/libQtGui.so.4
If I override mousePressEvent and mouseMoveEvent, these kinds of crashes no longer happen. Am I doing something wrong over here, or can I chalk this up as a bug in QtRuby?
I'm on fedora11, with the following packages installed:
QtRuby-4.4.0-1.fc11.i586
ruby-1.8.6.369-1.fc11.i586
These crashes also happen when running the script on Windows.
You're using a Qt::TableWidget when you should be using a Qt::TableView. The following code fixed the crash for me. In addition to a switch from Qt::TableWidget to Qt::TableView, I also reimplemented the index method, just in case. :)
require 'Qt4'
class SimpleModel < Qt::AbstractTableModel
def rowCount(parent)
return 1
end
def columnCount(parent)
return 1
end
def data(index, role=Qt::DisplayRole)
return Qt::Variant.new("Really Long String") if index.row == 0 and index.column == 0 and role == Qt::DisplayRole
return Qt::Variant.new
end
def index(row, column, parent)
if (row > 0 || column > 0)
return Qt::ModelIndex.new
else
return createIndex(row, column, 128*row*column)
end
end
end
Qt::Application.new(ARGV) do
Qt::TableView.new do
set_model SimpleModel.new
show
end
exec
end