<commit_before>##############################################################
# This is the model for the database table test_scripts,
# which each instance of this model represents a test script
# file submitted by the admin. It can be written in any
# scripting language (bash script, ruby, python etc.). The
# admin uploads the test script and saves in some repository
# in MarkUs. When a user sends a test request, MarkUs executes
# all the test scripts of the assignment, in the order
# specified by seq_num. The test script can assume all the
# test support files are in the same file directory to help
# running the test.
#
# The attributes of test_scripts are:
#   assignment_id:      id of the assignment
#   seq_num:            a floating point number indicates the
#                       order of the execution. The test script
#                       with the smallest seq_num executes first.
#   script_name:        name of the script
#   description:        a brief description of the script. It
#                       can be shown to the students. (optionally)
#   max_marks:          maximum point a test can get for this
#                       test. It can be any non-negative integer.
#   run_on_submission:  a boolean indicates if this script is run
#                       when student submits the assignment
#   run_on_request:     a boolean indicates if this script is run
#                       when a user sends a test request
#   halts_testing:      a boolean indicates if this script halts
#                       the test run when error occurs
#   display_description
#   display_run_status
#   display_marks_earned
#   display_input
#   display_expected_output
#   display_actual_output
#
#   The 6 attributes start with "display" have similar usages.
#   Each has a value of one of {"do_not_display",
#                               "display_after_submission",
#                               "display_after_collection"},
#   which indicates whether or not and when it is displayed
#   to the student.
##############################################################

class TestScript < ActiveRecord::Base
  belongs_to :assignment
  has_many :test_results, :dependent => :delete_all
  has_many :test_script_results, :dependent => :delete_all
  
  # Run sanitize_filename before saving to the database
  before_save :sanitize_filename
  
  # Upon update, if replacing a file with a different name, delete the old file first
  before_update :delete_old_file
  
  # Run write_file after saving to the database
  after_save :write_file
  
  # Run delete_file method after removal from db
  after_destroy :delete_file

  validates_presence_of :assignment
  validates_associated :assignment
  
  validates_presence_of :seq_num
  validates_presence_of :script_name
  validates_presence_of :max_marks
  validates_presence_of :description, :if => "description.nil?"
  
  # validates the uniqueness of script_name for the same assignment
  validates_each :script_name do |record, attr, value|
    # Extract script_name
    name = value
    if value.respond_to?(:original_filename)
      name = value.original_filename
    end

  #   # FIXME: create a loop to loop through all dup_file
  #   # dup_files = TestScript.find_all_by_assignment_id_and_script_name(record.assignment_id, name)
  #   dup_file = TestScript.find_by_assignment_id_and_script_name(record.assignment_id, name)
  #   if dup_file && dup_file.id != record.id
  #     record.errors.add attr, ' ' + name + ' ' + I18n.t("automated_tests.filename_exists")
  #   end
  # end
  #
  # # validates the uniqueness of seq_num for the same assignment
  # validates_each :seq_num do |record, attr, value|
  #   # FIXME: create a loop to loop through all dup_file
  #   # dup_files = TestScript.find_all_by_assignment_id_and_seq_num(record.assignment_id, value)
  #   dup_file = TestScript.find_by_assignment_id_and_seq_num(record.assignment_id, value)
  #   if dup_file && dup_file.id != record.id
  #     # FIXME: fix the error message: this is not filename
  #     record.errors.add attr, ' ' + value.to_s + ' ' + I18n.t("automated_tests.filename_exists")
  #   end
  end
  
  validates_numericality_of :seq_num
  validates_numericality_of :max_marks, :only_integer => true, :greater_than_or_equal_to => 0

  validates_presence_of :display_description
  validates_presence_of :display_run_status
  validates_presence_of :display_marks_earned
  validates_presence_of :display_input
  validates_presence_of :display_expected_output
  validates_presence_of :display_actual_output
  
  display_option = %w(do_not_display display_after_submission display_after_collection)
  validates_inclusion_of :display_description, :in => display_option<commit_msg>Update test_script.rb<commit_after>##############################################################
# This is the model for the database table test_scripts,
# which each instance of this model represents a test script
# file submitted by the admin. It can be written in any
# scripting language (bash script, ruby, python etc.). The
# admin uploads the test script and saves in some repository
# in MarkUs. When a user sends a test request, MarkUs executes
# all the test scripts of the assignment, in the order
# specified by seq_num. The test script can assume all the
# test support files are in the same file directory to help
# running the test.
#
# The attributes of test_scripts are:
#   assignment_id:      id of the assignment
#   seq_num:            a floating point number indicates the
#                       order of the execution. The test script
#                       with the smallest seq_num executes first.
#   script_name:        name of the script
#   description:        a brief description of the script. It
#                       can be shown to the students. (optionally)
#   max_marks:          maximum point a test can get for this
#                       test. It can be any non-negative integer.
#   run_on_submission:  a boolean indicates if this script is run
#                       when student submits the assignment
#   run_on_request:     a boolean indicates if this script is run
#                       when a user sends a test request
#   halts_testing:      a boolean indicates if this script halts
#                       the test run when error occurs
#   display_description
#   display_run_status
#   display_marks_earned
#   display_input
#   display_expected_output
#   display_actual_output
#
#   The 6 attributes start with "display" have similar usages.
#   Each has a value of one of {"do_not_display",
#                               "display_after_submission",
#                               "display_after_collection"},
#   which indicates whether or not and when it is displayed
#   to the student.
##############################################################

class TestScript < ActiveRecord::Base
  belongs_to :assignment
  has_many :test_results, :dependent => :delete_all
  has_many :test_script_results, :dependent => :delete_all
  
  # Run sanitize_filename before saving to the database
  before_save :sanitize_filename
  
  # Upon update, if replacing a file with a different name, delete the old file first
  before_update :delete_old_file
  
  # Run write_file after saving to the database
  after_save :write_file
  
  # Run delete_file method after removal from db
  after_destroy :delete_file

  validates_presence_of :assignment
  validates_associated :assignment
  
  validates_presence_of :seq_num
  validates_presence_of :script_name
  validates_presence_of :max_marks
  validates_presence_of :description, :if => "description.nil?"
  
  # validates the uniqueness of script_name for the same assignment
  validates_each :script_name do |record, attr, value|
    # Extract script_name
    name = value
    if value.respond_to?(:original_filename)
      name = value.original_filename
    end

    # FIXME: create a loop to loop through all dup_file
    # dup_files = TestScript.find_all_by_assignment_id_and_script_name(record.assignment_id, name)
    dup_file = TestScript.find_by_assignment_id_and_script_name(record.assignment_id, name)
    if dup_file && dup_file.id != record.id
      record.errors.add attr, ' ' + name + ' ' + I18n.t("automated_tests.filename_exists")
    end
  end
  
  # validates the uniqueness of seq_num for the same assignment
  validates_each :seq_num do |record, attr, value|
    # FIXME: create a loop to loop through all dup_file
    # dup_files = TestScript.find_all_by_assignment_id_and_seq_num(record.assignment_id, value)
    dup_file = TestScript.find_by_assignment_id_and_seq_num(record.assignment_id, value)
    if dup_file && dup_file.id != record.id
      # FIXME: fix the error message: this is not filename
      record.errors.add attr, ' ' + value.to_s + ' ' + I18n.t("automated_tests.filename_exists")
    end
  end
  
  validates_numericality_of :seq_num
  validates_numericality_of :max_marks, :only_integer => true, :greater_than_or_equal_to => 0

  validates_presence_of :display_description
  validates_presence_of :display_run_status
  validates_presence_of :display_marks_earned
  validates_presence_of :display_input
  validates_presence_of :display_expected_output
  validates_presence_of :display_actual_output
  
  display_option = %w(do_not_display display_after_submission display_after_collection)
  validates_inclusion_of :display_description, :in => display_option
{'fraction_non_alphanumeric': 0.08189243661822425, 'fraction_numerical': 0.0012729394292988225, 'mean_word_length': 3.500238663484487, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4006018', 'n_tokens_mistral': 2714, 'n_tokens_neox': 2671, 'n_words': 878}