-1

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

Tarun Rawat
  • 35
  • 1
  • 8
  • 2
    just use local variables inside the block: `@@tc_array.each do |tc| ... end` – Ilya May 02 '17 at 11:35
  • 4
    I'm so sorry that you have to learn ruby from this code... – Mark Thomas May 02 '17 at 11:39
  • @Ilya, actually this code is working fine with Ruby-1.8.7. Now i am checking with Ruby-2.4.1 . Is there any change in assignment semantics in these version ? – Tarun Rawat May 02 '17 at 12:04
  • Could you give a full code snippet where this is coming from? – Maxim Fedotov May 02 '17 at 12:17
  • 1
    @TarunRawat Yes, there are lots of minor changes like this , especially between `1.8` --> `1.9` --> `2.0`. Note that these versions are no longer supported - you should aim to be using at least `2.2`, and ideally (the latest) `2.4.1`. – Tom Lord May 02 '17 at 12:29
  • @MaximFedotov , snippet has been added – Tarun Rawat May 02 '17 at 12:40
  • @TomLord , then how i can correct this in code [written in ruby-1.8.7] . Is there any document available ? – Tarun Rawat May 02 '17 at 12:41
  • 3
    Jesus.... I'd rather just re-write that than try to "fix" it! Whoever wrote it ("a long time ago") clearly didn't know what they were doing -- you've essentially got global variables flying around all over the place. – Tom Lord May 02 '17 at 12:47
  • At the very least, try to remove `@@` from all the variable names (if you can?!), and re-name variables to something sensible - e.g. `@@m` --> `current_method_name` – Tom Lord May 02 '17 at 12:50
  • 1
    While you're at it, `git blame` the file and send them a very angry email. – Tom Lord May 02 '17 at 12:59
  • I've seen you're following @Ilya's advice, but keep in mind you have to change references for `@@tc` inside the `@@tc_array.each` block. You should replace `@@tc` for `tc`. – Alexandre Angelim May 02 '17 at 13:16
  • @TarunRawat: Every release of Ruby comes with release documents describing the changes from the previous release. So, if you want to know all the changes between Ruby 1.8.7 and Ruby 2.4.1, you can read all the release documents for Ruby 1.9.0, 1.9.1, 1.9.2, 1.9.3, 2.0.0, 2.1.0, 2.1.1, 2.1.2, 2.1.3, 2.1.4, 2.1.5, 2.1.6, 2.1.7, 2.1.8, 2.1.9, 2.2.0, 2.2.1, 2.2.2, 2.2.3, 2.2.4, 2.2.5, 2.2.6, 2.2.7, 2.3.0., 2.3.1, 2.3.2, 2.3.3, 2.3.4, 2.4.0, and 2.4.1. – Jörg W Mittag May 02 '17 at 14:15
  • I cannot reproduce your problem, and the code that is mentioned in the error message doesn't actually appear in your code. – Jörg W Mittag May 02 '17 at 14:21
  • @JörgWMittag : I have corrected the line in above snippet, now error should be re-produced at your end. Thanks for providing info related to release documents – Tarun Rawat May 03 '17 at 04:54

1 Answers1

0

This is fixed now after making "tc" as local variable.

Tarun Rawat
  • 35
  • 1
  • 8