diff --git a/.gitignore b/.gitignore index 8aa63f4..53c6913 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .idea pkg reports +coverage +*.gem \ No newline at end of file diff --git a/.ruby-gemset b/.ruby-gemset new file mode 100644 index 0000000..3b2e86b --- /dev/null +++ b/.ruby-gemset @@ -0,0 +1 @@ +testlink-api-client \ No newline at end of file diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..b2eb314 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +ruby-2.6.3 \ No newline at end of file diff --git a/.rvmrc b/.rvmrc deleted file mode 100644 index 486c817..0000000 --- a/.rvmrc +++ /dev/null @@ -1 +0,0 @@ -rvm 1.9.2@testlink-api-client --create diff --git a/README.rdoc b/README.rdoc index 52a60aa..eca9c35 100644 --- a/README.rdoc +++ b/README.rdoc @@ -4,7 +4,7 @@ This gem provides an endpoint for TestLink Remote API == Installation In a shell, just run: - $ gem install teslink-api-client + $ gem install testlink-api-client == How to use it @@ -18,4 +18,20 @@ To use this library you just need to require the gem: tl.getProjects #Will return an Array of TestLink::Objects::Project == Bug Reporting -If you find any bug, please feel free to report it at https://github.com/floreal/testlink-api-client/issues \ No newline at end of file +If you find any bug, please feel free to report it at https://github.com/floreal/testlink-api-client/issues + +== Contribution + +1. Fork on Github +2. `gem install rspec` +3. `gem install autotest-growl` +4. `gem install autotest` +5. `gem install cucumber` +6. `gem install simplecov` +7. `rspec spec` +8. In forked repo, create feature branch + +== Build + +gem build testlink-api-client.gem +gem install ./testlink-api-client-version.gem \ No newline at end of file diff --git a/features/step_definitions/common.rb b/features/step_definitions/common.rb index 40f0921..c4ae87c 100644 --- a/features/step_definitions/common.rb +++ b/features/step_definitions/common.rb @@ -39,23 +39,23 @@ Then /^A response error exception is raised with a message "([^"]*)"$/ do |message| fail "Received a non error response \"#{@result}\" when expecting an error message: #{message}" if @error.nil? - @error.class.should < TestLink::Exceptions::Exception - @error.message.should == message + expect(@error.class).to be < TestLink::Exceptions::Exception + expect(@error.message).to eq message end Then /^I get status "([^"]*)" for "([^"]*)" with additionalInfo "([^"]*)" and message "([^"]*)"$/ do |status, operation, info, message| fail "Received an error \"#{@error}\" when expecting a success" unless @error.nil? - @result.count.should == 1 + expect(@result.count).to eq 1 returned_status = @result.first - returned_status.should be_instance_of TestLink::Objects::Status - returned_status.status.should == string2boolean(status) - returned_status.operation.should == operation - returned_status.additional_info.should == info - returned_status.message.should == message + expect(returned_status).to be_instance_of TestLink::Objects::Status + expect(returned_status.status).to eq string2boolean(status) + expect(returned_status.operation).to eq operation + expect(returned_status.additional_info).to eq info + expect(returned_status.message).to eq message end Then /^I get this node list:$/ do |table| - @result.should == table.hashes.map { |row| + expect(@result).to eq table.hashes.map { |row| node = TestLink::Objects::Node.new node.id = row['id'].to_i if node.parent_id = row['parent_id'].to_i diff --git a/features/step_definitions/get_projects.rb b/features/step_definitions/get_projects.rb index a1dad10..cb838eb 100644 --- a/features/step_definitions/get_projects.rb +++ b/features/step_definitions/get_projects.rb @@ -43,7 +43,7 @@ end Then /^I get this Project list:$/ do |table| - @result.should == table.hashes.map { |row| + expect(@result).to eq table.hashes.map { |row| project = TestLink::Objects::Project.new project.id = row['id'].to_i project.notes = row['notes'].to_s diff --git a/lib/test_link.rb b/lib/test_link.rb index 0bb8a6f..0cf6e78 100644 --- a/lib/test_link.rb +++ b/lib/test_link.rb @@ -17,6 +17,8 @@ require 'test_link/command' require 'test_link/adapters' require 'test_link/exceptions' +require 'test_link/objects' +require 'test_link/enums' module TestLink end \ No newline at end of file diff --git a/lib/test_link/api_link.rb b/lib/test_link/api_link.rb index 421ae87..1ccb8ad 100644 --- a/lib/test_link/api_link.rb +++ b/lib/test_link/api_link.rb @@ -18,17 +18,22 @@ module TestLink class ApiLink attr_accessor :key - attr_reader :client, :url + attr_reader :client, :url, :version @@remote_methods = {} @@adapters = {} - def initialize(url, key) + def initialize(url, key, version = :v0) @url = url @key = key + @version = version @client = XMLRPC::Client.new2 self.api_url end def api_url() - @url + '/lib/api/xmlrpc.php' + if @version == :v1 + @url + '/lib/api/xmlrpc/v1/xmlrpc.php' + else + @url + '/lib/api/xmlrpc.php' + end end def self.remote_method(klass) diff --git a/lib/test_link/command.rb b/lib/test_link/command.rb index e1f406d..21a5213 100644 --- a/lib/test_link/command.rb +++ b/lib/test_link/command.rb @@ -22,6 +22,10 @@ require 'test_link/command/get_test_suites_for_test_suite' require 'test_link/command/get_test_suite_by_id' require 'test_link/command/create_test_case' +require 'test_link/command/report_test_case_result' +require 'test_link/command/get_test_cases_for_test_suite' +require 'test_link/command/get_project_test_plans' +require 'test_link/command/get_latest_build_for_test_plan' module TestLink module Command diff --git a/lib/test_link/command/get_latest_build_for_test_plan.rb b/lib/test_link/command/get_latest_build_for_test_plan.rb new file mode 100644 index 0000000..7e79dbf --- /dev/null +++ b/lib/test_link/command/get_latest_build_for_test_plan.rb @@ -0,0 +1,29 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require 'test_link/command/base' +require 'test_link/adapters/node_adapter' + +module TestLink + module Command + class GetLatestBuildForTestPlan < Base + remote_method + + argument :testplanid, :mandatory => true + + adapt_with Adapters::NodeAdapter + end + end +end diff --git a/lib/test_link/command/get_project_test_plans.rb b/lib/test_link/command/get_project_test_plans.rb new file mode 100644 index 0000000..630b4b4 --- /dev/null +++ b/lib/test_link/command/get_project_test_plans.rb @@ -0,0 +1,29 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require 'test_link/command/base' +require 'test_link/adapters/node_adapter' + +module TestLink + module Command + class GetProjectTestPlans < Base + remote_method + + argument :testprojectid, :mandatory => true + + adapt_with Adapters::NodeAdapter + end + end +end diff --git a/lib/test_link/command/get_test_cases_for_test_suite.rb b/lib/test_link/command/get_test_cases_for_test_suite.rb new file mode 100644 index 0000000..c550486 --- /dev/null +++ b/lib/test_link/command/get_test_cases_for_test_suite.rb @@ -0,0 +1,31 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require 'test_link/command/base' +require 'test_link/adapters/node_adapter' + +module TestLink + module Command + class GetTestCasesForTestSuite < Base + remote_method + + argument :testsuiteid, :mandatory => true + argument :deep + argument :details + + adapt_with Adapters::NodeAdapter + end + end +end diff --git a/lib/test_link/command/report_test_case_result.rb b/lib/test_link/command/report_test_case_result.rb new file mode 100644 index 0000000..32775a0 --- /dev/null +++ b/lib/test_link/command/report_test_case_result.rb @@ -0,0 +1,39 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require 'test_link/command/base' +require 'test_link/adapters/status_adapter' + +module TestLink + module Command + class ReportTCResult < Base + remote_method + + argument :testcaseid, :mandatory => true + argument :testplanid, :mandatory => true + argument :status, :mandatory => true + argument :buildid + argument :buildname + argument :notes + argument :guess + argument :bugid + argument :platformid + argument :platformname + argument :customfields + + adapt_with Adapters::StatusAdapter + end + end +end diff --git a/lib/test_link/enums.rb b/lib/test_link/enums.rb new file mode 100644 index 0000000..dd5def4 --- /dev/null +++ b/lib/test_link/enums.rb @@ -0,0 +1,21 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require 'test_link/enums/valid_status_list' + +module TestLink + module Enums + end +end \ No newline at end of file diff --git a/lib/test_link/enums/valid_status_list.rb b/lib/test_link/enums/valid_status_list.rb new file mode 100644 index 0000000..0e27b35 --- /dev/null +++ b/lib/test_link/enums/valid_status_list.rb @@ -0,0 +1,28 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +module TestLink + module Enums + module ValidStatusList + FAILED = 'f' + BLOCKED = 'b' + PASSED = 'p' + NOT_RUN = 'n' + NOT_AVAILABLE = 'x' + UNKNOWN = 'u' + ALL = 'a' + end + end +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 12d4c7e..79d3ec6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -12,6 +12,11 @@ # # You should have received a copy of the GNU General Public License # along with testlink-api-client. If not, see . +require 'rspec/expectations' +require 'simplecov' +SimpleCov.start do + enable_coverage :branch +end module RSpec::Matchers def attribute_provided? object, attribute diff --git a/spec/test_link/adapters/base_spec.rb b/spec/test_link/adapters/base_spec.rb index deee324..df4f275 100644 --- a/spec/test_link/adapters/base_spec.rb +++ b/spec/test_link/adapters/base_spec.rb @@ -23,7 +23,7 @@ end it "manages responses" do - @adapter.should provide :response + expect(@adapter).to provide :response end it "raises an exception when an error code is detected in the response" do @@ -45,7 +45,7 @@ def @adapter.adapt_row row end @adapter.response = [{'name' => 'a'}, {'name' => 'b'}] - @adapter.response.each { |row| @adapter.should_receive(:adapt_row).with(row) } + @adapter.response.each { |row| allow(@adapter).to receive(:adapt_row).with(row) } @adapter.adapt end diff --git a/spec/test_link/adapters/node_adapter_spec.rb b/spec/test_link/adapters/node_adapter_spec.rb index be207c8..b85a19e 100644 --- a/spec/test_link/adapters/node_adapter_spec.rb +++ b/spec/test_link/adapters/node_adapter_spec.rb @@ -22,7 +22,7 @@ end it "inherits from TestLink::Adapters::Base" do - TestLink::Adapters::NodeAdapter.should < TestLink::Adapters::Base + expect(TestLink::Adapters::NodeAdapter).to be < TestLink::Adapters::Base end it "should know how to adapt a single row of a response" do @@ -34,7 +34,7 @@ "node_table" => node.table = "testsuites", "name" => node.name = "First Testsuite"} - @adapter.adapt_row(row).should == node + expect(@adapter.adapt_row(row)).to eq node end it "should should adapt raw response to Project objects" do @@ -56,7 +56,7 @@ "name" => node2.name = "Second Testsuite"}] @adapter.response = response - @adapter.adapt.should == [ node1, node2 ] + expect(@adapter.adapt).to eq [ node1, node2 ] end describe "workaround unexpected messages form" do @@ -81,7 +81,7 @@ "parent_id"=> (node2.parent_id = 2).to_s}} @adapter.response = response - @adapter.adapt.should == [ node1, node2 ] + expect(@adapter.adapt).to eq [ node1, node2 ] end it 'allows to receive a single node out of an array' do @@ -96,7 +96,7 @@ "parent_id" => (node.parent_id = 2).to_s} @adapter.response = response - @adapter.adapt.should == [ node ] + expect(@adapter.adapt).to eq [ node ] end end end \ No newline at end of file diff --git a/spec/test_link/adapters/project_adapter_spec.rb b/spec/test_link/adapters/project_adapter_spec.rb index f6ee220..9d856a7 100644 --- a/spec/test_link/adapters/project_adapter_spec.rb +++ b/spec/test_link/adapters/project_adapter_spec.rb @@ -22,7 +22,7 @@ end it "inherits from TestLink::Adapters::Base" do - TestLink::Adapters::ProjectAdapter.should < TestLink::Adapters::Base + expect(TestLink::Adapters::ProjectAdapter).to be < TestLink::Adapters::Base end it "should know how to adapt a single row of a response" do @@ -41,10 +41,10 @@ "automationEnabled"=>"1", "inventoryEnabled"=>false}} - @project_adapter.adapt_row(row).should == p_formation + expect(@project_adapter.adapt_row(row)).to eq p_formation end - it "should should adapt raw response to Project objects" do + it "should adapt raw response to Project objects" do p_formation = TestLink::Objects::Project.new p_val = TestLink::Objects::Project.new response = [ @@ -76,6 +76,6 @@ "inventoryEnabled"=>false}}] @project_adapter.response = response - @project_adapter.adapt.should == [ p_formation, p_val ] + expect(@project_adapter.adapt).to eq [ p_formation, p_val ] end end \ No newline at end of file diff --git a/spec/test_link/adapters/status_adapter_spec.rb b/spec/test_link/adapters/status_adapter_spec.rb index 20c9fc2..bcb7008 100644 --- a/spec/test_link/adapters/status_adapter_spec.rb +++ b/spec/test_link/adapters/status_adapter_spec.rb @@ -22,7 +22,7 @@ end it "inherits from TestLink::Adapters::Base" do - TestLink::Adapters::StatusAdapter.should < TestLink::Adapters::Base + expect(TestLink::Adapters::StatusAdapter).to be < TestLink::Adapters::Base end it "knows how to adapt a single row of a response" do @@ -33,7 +33,7 @@ "operation" => status.operation = "createTestSuite", "additionalInfo" => status.additional_info = "some more infos", "message" => status.message = "ok"} - @status_adapter.adapt_row(row).should == status + expect(@status_adapter.adapt_row(row)).to eq status end it "should should adapt raw response to Status objects" do @@ -46,6 +46,6 @@ "message" => status.message = "ok"}] @status_adapter.response = response - @status_adapter.adapt.should == [ status ] + expect(@status_adapter.adapt).to eq [ status ] end end \ No newline at end of file diff --git a/spec/test_link/api_link_spec.rb b/spec/test_link/api_link_spec.rb index bded3d5..027df9a 100644 --- a/spec/test_link/api_link_spec.rb +++ b/spec/test_link/api_link_spec.rb @@ -21,30 +21,37 @@ @url = 'http://qa.example.com' @key = '__dev_key__' @link = TestLink::ApiLink.new @url, @key + @link_v1 = TestLink::ApiLink.new @url, @key, :v1 end it 'has a server url' do - @link.url.should == @url + expect(@link.url).to eq @url end it 'has an API key' do - @link.key.should == @key + expect(@link.key).to eq @key end it 'has an API url' do - @link.api_url.should == (@url + '/lib/api/xmlrpc.php') + expect(@link.api_url).to eq(@url + '/lib/api/xmlrpc.php') + expect(@link_v1.api_url).to eq(@url + '/lib/api/xmlrpc/v1/xmlrpc.php') + end + + it 'has and API version' do + expect(@link.version).to eq(:v0) + expect(@link_v1.version).to eq(:v1) end it 'holds a XMLRPC client' do - @link.client.should be_an_instance_of XMLRPC::Client + expect(@link.client).to be_an_instance_of XMLRPC::Client end it 'allows to add remote methods' do - TestLink::ApiLink.should respond_to :remote_method + expect(TestLink::ApiLink).to respond_to :remote_method end it 'allows to define an adapter for each remote method' do - TestLink::ApiLink.should respond_to :set_adapter_for + expect(TestLink::ApiLink).to respond_to :set_adapter_for end describe 'Adding remote method support' do @@ -78,11 +85,11 @@ def execute link it 'finds out the name of the method with class command_name method' do link = TestLink::ApiLink.new('http://qa.example.com/', '') - link.should respond_to :foo + expect(link).to respond_to :foo end it 'registers a new class instance with the command symbol' do - TestLink::ApiLink.remote_methods[:foo].should be_an_instance_of Foo + expect(TestLink::ApiLink.remote_methods[:foo]).to be_an_instance_of Foo end describe 'execution' do @@ -93,13 +100,13 @@ def execute link it 'calls the registered command class execute method with parameters' do args = {:foo => 'bar', :baz => 42} foo = TestLink::ApiLink.remote_methods[:foo] - foo.should_receive(:execute).with(@link) - foo.should_receive(:reset_arguments_hash).with(args) + allow(foo).to receive(:execute).with(@link) + allow(foo).to receive(:reset_arguments_hash).with(args) @link.foo args end it 'uses the command specified adapter' do - TestLink::ApiLink.adapter_for(Foo.command_name.to_sym).should be_an_instance_of FooAdapter + expect(TestLink::ApiLink.adapter_for(Foo.command_name.to_sym)).to be_an_instance_of FooAdapter end end end diff --git a/spec/test_link/command/argument_spec.rb b/spec/test_link/command/argument_spec.rb index 5c6d60c..3c8839b 100644 --- a/spec/test_link/command/argument_spec.rb +++ b/spec/test_link/command/argument_spec.rb @@ -22,22 +22,22 @@ end it 'has a default value' do - @argument.should respond_to :default + expect(@argument).to respond_to :default end it 'may be mandatory' do - @argument.should respond_to :mandatory? + expect(@argument).to respond_to :mandatory? end describe 'default state' do describe 'default value' do it 'is nil' do - @argument.default.should be_nil + expect(@argument.default).to be_nil end end it 'is not mandatory' do - @argument.mandatory?.should be_false + expect(@argument.mandatory?).to be_falsy end end end \ No newline at end of file diff --git a/spec/test_link/command/base_spec.rb b/spec/test_link/command/base_spec.rb index 6df4fe2..2bc1a8b 100644 --- a/spec/test_link/command/base_spec.rb +++ b/spec/test_link/command/base_spec.rb @@ -23,22 +23,22 @@ describe 'Arguments' do it 'can be defined' do - TestLink::Command::Base.should respond_to :argument + expect(TestLink::Command::Base).to respond_to :argument end it 'has an argument list' do - TestLink::Command::Base.should respond_to :arguments + expect(TestLink::Command::Base).to respond_to :arguments end it 'has dev_key mandatory argument' do - TestLink::Command::Base.arguments[:devKey].mandatory?.should be_true - @command.should provide :devKey + expect(TestLink::Command::Base.arguments[:devKey].mandatory?).to be_truthy + expect(@command).to provide :devKey end end describe 'Classname' do it 'helps to retrieve remote command name the first letter becomes lower case' do - TestLink::Command::Base.command_name.should == 'base' + expect(TestLink::Command::Base.command_name).to eq 'base' end end @@ -46,26 +46,26 @@ before :each do @key = '___dev-key___' @link = TestLink::ApiLink.new 'http://qa.example.com/', @key - @link.client.stub!(:call) + @link.client.stub(:call) end it 'calls a remote method' do - @link.client.should_receive(:call).with('tl.base', :devKey => @key) + expect(@link.client).to receive(:call).with('tl.base', :devKey => @key) @command.execute @link end it 'sets a default developer key given by the link' do @command.execute @link - @command.devKey.should == @key - @command.arguments_hash[:devKey].should == @key + expect(@command.devKey).to eq @key + expect(@command.arguments_hash[:devKey]).to eq @key end it 'overrides the link\'s key if it is defined' do key = '___other-dev-key___' @command.devKey = key @command.execute @link - @command.devKey.should == key - @command.arguments_hash[:devKey].should == key + expect(@command.devKey).to eq key + expect(@command.arguments_hash[:devKey]).to eq key end it 'raise an ArgumentError when a mandatory is not set' do @@ -76,19 +76,19 @@ it 'allows to reset arguments to defined values' do @command.reset_arguments_hash :devKey => (key = 'my_dev_key') - @command.devKey.should == key - @command.arguments_hash[:devKey].should == key + expect(@command.devKey).to eq key + expect(@command.arguments_hash[:devKey]).to eq key end it 'checks whether command can be executed' do - TestLink::Command::Base.new.check_arguments.should == [:devKey] + expect(TestLink::Command::Base.new.check_arguments).to eq [:devKey] end it 'can add itself to TestLink::ApiLink' do - TestLink::Command::Base.should respond_to :remote_method + expect(TestLink::Command::Base).to respond_to :remote_method end it 'defines it\'s adapter' do - TestLink::Command::Base.should respond_to :adapt_with + expect(TestLink::Command::Base).to respond_to :adapt_with end end \ No newline at end of file diff --git a/spec/test_link/command/create_test_case_spec.rb b/spec/test_link/command/create_test_case_spec.rb index bd58cb3..42ff875 100644 --- a/spec/test_link/command/create_test_case_spec.rb +++ b/spec/test_link/command/create_test_case_spec.rb @@ -18,16 +18,16 @@ describe TestLink::Command::CreateTestCase do it "is a command" do - TestLink::Command::CreateTestCase.should < TestLink::Command::Base + expect(TestLink::Command::CreateTestCase).to be < TestLink::Command::Base end - it "adds a createTestSuite method to TestLink::ApiLink" do - TestLink::ApiLink.new('http://qa.example.com/', '').should respond_to :createTestCase + it "adds a createTestCase method to TestLink::ApiLink" do + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :createTestCase end describe 'adapter' do it 'is a TestLink::Adapters::StatusAdapter' do - TestLink::ApiLink.adapter_for(TestLink::Command::CreateTestCase.command_name).should be_instance_of TestLink::Adapters::StatusAdapter + expect(TestLink::ApiLink.adapter_for(TestLink::Command::CreateTestCase.command_name)).to be_instance_of TestLink::Adapters::StatusAdapter end end @@ -37,51 +37,51 @@ end it 'contain mandatory testcasename' do - @command.should provide_mandatory_argument :testcasename + expect(@command).to provide_mandatory_argument :testcasename end it 'contain mandatory testsuiteid' do - @command.should provide_mandatory_argument :testsuiteid + expect(@command).to provide_mandatory_argument :testsuiteid end it 'contain mandatory testprojectid' do - @command.should provide_mandatory_argument :testprojectid + expect(@command).to provide_mandatory_argument :testprojectid end it 'contain mandatory authorlogin' do - @command.should provide_mandatory_argument :authorlogin + expect(@command).to provide_mandatory_argument :authorlogin end it 'contain mandatory summary' do - @command.should provide_mandatory_argument :summary + expect(@command).to provide_mandatory_argument :summary end it 'contain mandatory steps' do - @command.should provide_mandatory_argument :steps + expect(@command).to provide_mandatory_argument :steps end it 'contain preconditions' do - @command.should provide_argument :preconditions + expect(@command).to provide_argument :preconditions end it 'contain importance' do - @command.should provide_argument :importance + expect(@command).to provide_argument :importance end it 'contain execution' do - @command.should provide_argument :execution + expect(@command).to provide_argument :execution end it 'contain order' do - @command.should provide_argument :order + expect(@command).to provide_argument :order end it 'contain checkduplicatedname' do - @command.should provide_argument :checkduplicatedname + expect(@command).to provide_argument :checkduplicatedname end it 'contain actiononduplicatedname' do - @command.should provide_argument :actiononduplicatedname + expect(@command).to provide_argument :actiononduplicatedname end end diff --git a/spec/test_link/command/create_test_suite_spec.rb b/spec/test_link/command/create_test_suite_spec.rb index 23f1cac..d09a522 100644 --- a/spec/test_link/command/create_test_suite_spec.rb +++ b/spec/test_link/command/create_test_suite_spec.rb @@ -18,16 +18,16 @@ describe TestLink::Command::CreateTestSuite do it "is a command" do - (TestLink::Command::CreateTestSuite < TestLink::Command::Base).should be_true + expect(TestLink::Command::CreateTestSuite < TestLink::Command::Base).to be_truthy end it "adds a createTestSuite method to TestLink::ApiLink" do - TestLink::ApiLink.new('http://qa.example.com/', '').should respond_to :createTestSuite + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :createTestSuite end describe 'adapter' do it 'is a TestLink::Adapters::StatusAdapter' do - TestLink::ApiLink.adapter_for(TestLink::Command::CreateTestSuite.command_name).should be_instance_of TestLink::Adapters::StatusAdapter + expect(TestLink::ApiLink.adapter_for(TestLink::Command::CreateTestSuite.command_name)).to be_instance_of TestLink::Adapters::StatusAdapter end end @@ -37,31 +37,31 @@ end it 'contain mandatory testprojectid' do - @command.should provide_mandatory_argument :testprojectid + expect(@command).to provide_mandatory_argument :testprojectid end it 'contain mandatory testsuitename' do - @command.should provide_mandatory_argument :testsuitename + expect(@command).to provide_mandatory_argument :testsuitename end it 'contain mandatory details' do - @command.should provide_mandatory_argument :details + expect(@command).to provide_mandatory_argument :details end it 'contain checkduplicatedname' do - @command.should provide_argument :checkduplicatedname + expect(@command).to provide_argument :checkduplicatedname end it 'contain actiononduplicatedname' do - @command.should provide_argument :actiononduplicatedname + expect(@command).to provide_argument :actiononduplicatedname end it 'contain parentid' do - @command.should provide_argument :parentid + expect(@command).to provide_argument :parentid end it 'contain order' do - @command.should provide_argument :order + expect(@command).to provide_argument :order end end end \ No newline at end of file diff --git a/spec/test_link/command/get_first_level_test_suites_for_test_project_spec.rb b/spec/test_link/command/get_first_level_test_suites_for_test_project_spec.rb index e956df1..ca25049 100644 --- a/spec/test_link/command/get_first_level_test_suites_for_test_project_spec.rb +++ b/spec/test_link/command/get_first_level_test_suites_for_test_project_spec.rb @@ -18,16 +18,16 @@ describe TestLink::Command::GetFirstLevelTestSuitesForTestProject do it "is a command" do - TestLink::Command::GetFirstLevelTestSuitesForTestProject.should < TestLink::Command::Base + expect(TestLink::Command::GetFirstLevelTestSuitesForTestProject).to be < TestLink::Command::Base end it "adds a getFirstLevelTestSuitesForTestProject method to TestLink::ApiLink" do - TestLink::ApiLink.new('http://qa.example.com/', '').should respond_to :getFirstLevelTestSuitesForTestProject + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :getFirstLevelTestSuitesForTestProject end describe 'adapter' do it 'is a TestLink::Adapters::NodeAdapter' do - TestLink::ApiLink.adapter_for(TestLink::Command::GetFirstLevelTestSuitesForTestProject.command_name).should be_instance_of TestLink::Adapters::NodeAdapter + expect(TestLink::ApiLink.adapter_for(TestLink::Command::GetFirstLevelTestSuitesForTestProject.command_name)).to be_instance_of TestLink::Adapters::NodeAdapter end end @@ -37,7 +37,7 @@ end it 'contain mandatory testprojectid' do - @command.should provide_mandatory_argument :testprojectid + expect(@command).to provide_mandatory_argument :testprojectid end end end \ No newline at end of file diff --git a/spec/test_link/command/get_latest_build_for_test_plan_spec.rb b/spec/test_link/command/get_latest_build_for_test_plan_spec.rb new file mode 100644 index 0000000..654d88b --- /dev/null +++ b/spec/test_link/command/get_latest_build_for_test_plan_spec.rb @@ -0,0 +1,44 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require "test_link/command/get_latest_build_for_test_plan" +require "test_link/adapters/status_adapter" + +describe TestLink::Command::GetLatestBuildForTestPlan do + it "is a command" do + expect(TestLink::Command::GetLatestBuildForTestPlan).to be < TestLink::Command::Base + end + + it "adds a GetLatestBuildForTestPlan method to TestLink::ApiLink" do + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :getLatestBuildForTestPlan + end + + describe 'adapter' do + it 'is a TestLink::Adapters::NodeAdapter' do + expect(TestLink::ApiLink.adapter_for(TestLink::Command::GetLatestBuildForTestPlan.command_name)).to be_instance_of TestLink::Adapters::NodeAdapter + end + end + + describe 'arguments' do + before :each do + @command = TestLink::Command::GetLatestBuildForTestPlan.new + end + + it 'contain mandatory testplanid' do + expect(@command).to provide_mandatory_argument :testplanid + end + + end +end \ No newline at end of file diff --git a/spec/test_link/command/get_project_test_plans_spec.rb b/spec/test_link/command/get_project_test_plans_spec.rb new file mode 100644 index 0000000..bb7bbab --- /dev/null +++ b/spec/test_link/command/get_project_test_plans_spec.rb @@ -0,0 +1,44 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require "test_link/command/get_project_test_plans" +require "test_link/adapters/status_adapter" + +describe TestLink::Command::GetProjectTestPlans do + it "is a command" do + expect(TestLink::Command::GetProjectTestPlans).to be < TestLink::Command::Base + end + + it "adds a GetProjectTestPlans method to TestLink::ApiLink" do + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :getProjectTestPlans + end + + describe 'adapter' do + it 'is a TestLink::Adapters::NodeAdapter' do + expect(TestLink::ApiLink.adapter_for(TestLink::Command::GetProjectTestPlans.command_name)).to be_instance_of TestLink::Adapters::NodeAdapter + end + end + + describe 'arguments' do + before :each do + @command = TestLink::Command::GetProjectTestPlans.new + end + + it 'contain mandatory testprojectid' do + expect(@command).to provide_mandatory_argument :testprojectid + end + + end +end \ No newline at end of file diff --git a/spec/test_link/command/get_projets_spec.rb b/spec/test_link/command/get_projects_spec.rb similarity index 77% rename from spec/test_link/command/get_projets_spec.rb rename to spec/test_link/command/get_projects_spec.rb index 71e61f1..65f2858 100644 --- a/spec/test_link/command/get_projets_spec.rb +++ b/spec/test_link/command/get_projects_spec.rb @@ -18,16 +18,16 @@ describe TestLink::Command::GetProjects do it "is a command" do - TestLink::Command::GetProjects.should < TestLink::Command::Base + expect(TestLink::Command::GetProjects).to be < TestLink::Command::Base end it "adds a getProjects method to TestLink::ApiLink" do - TestLink::ApiLink.new('http://qa.example.com/', '').should respond_to :getProjects + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :getProjects end describe 'adapter' do it 'is a TestLink::Adapters::ProjectAdapter' do - TestLink::ApiLink.adapter_for(TestLink::Command::GetProjects.command_name).should be_instance_of TestLink::Adapters::ProjectAdapter + expect(TestLink::ApiLink.adapter_for(TestLink::Command::GetProjects.command_name)).to be_instance_of TestLink::Adapters::ProjectAdapter end end end \ No newline at end of file diff --git a/spec/test_link/command/get_test_cases_for_test_suite_spec.rb b/spec/test_link/command/get_test_cases_for_test_suite_spec.rb new file mode 100644 index 0000000..1f5fce4 --- /dev/null +++ b/spec/test_link/command/get_test_cases_for_test_suite_spec.rb @@ -0,0 +1,52 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require "test_link/command/get_test_cases_for_test_suite" +require "test_link/adapters/status_adapter" + +describe TestLink::Command::GetTestCasesForTestSuite do + it "is a command" do + expect(TestLink::Command::GetTestCasesForTestSuite).to be < TestLink::Command::Base + end + + it "adds a GetTestCasesForTestSuite method to TestLink::ApiLink" do + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :getTestCasesForTestSuite + end + + describe 'adapter' do + it 'is a TestLink::Adapters::NodeAdapter' do + expect(TestLink::ApiLink.adapter_for(TestLink::Command::GetTestCasesForTestSuite.command_name)).to be_instance_of TestLink::Adapters::NodeAdapter + end + end + + describe 'arguments' do + before :each do + @command = TestLink::Command::GetTestCasesForTestSuite.new + end + + it 'contain mandatory testsuiteid' do + expect(@command).to provide_mandatory_argument :testsuiteid + end + + it 'contain deep' do + expect(@command).to provide_argument :deep + end + + it 'contain details' do + expect(@command).to provide_argument :details + end + + end +end \ No newline at end of file diff --git a/spec/test_link/command/get_test_suite_by_id_spec.rb b/spec/test_link/command/get_test_suite_by_id_spec.rb index 04d5a97..d580c4a 100644 --- a/spec/test_link/command/get_test_suite_by_id_spec.rb +++ b/spec/test_link/command/get_test_suite_by_id_spec.rb @@ -18,16 +18,16 @@ describe TestLink::Command::GetTestSuiteByID do it "is a command" do - TestLink::Command::GetTestSuiteByID.should < TestLink::Command::Base + expect(TestLink::Command::GetTestSuiteByID).to be < TestLink::Command::Base end it "adds a getTestSuiteByID method to TestLink::ApiLink" do - TestLink::ApiLink.new('http://qa.example.com/', '').should respond_to :getTestSuiteByID + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :getTestSuiteByID end describe 'adapter' do it 'is a TestLink::Adapters::NodeAdapter' do - TestLink::ApiLink.adapter_for(TestLink::Command::GetTestSuiteByID.command_name).should be_instance_of TestLink::Adapters::NodeAdapter + expect(TestLink::ApiLink.adapter_for(TestLink::Command::GetTestSuiteByID.command_name)).to be_instance_of TestLink::Adapters::NodeAdapter end end @@ -37,7 +37,7 @@ end it 'contain mandatory testsuiteid' do - @command.should provide_mandatory_argument :testsuiteid + expect(@command).to provide_mandatory_argument :testsuiteid end end end \ No newline at end of file diff --git a/spec/test_link/command/get_test_suites_for_test_suite_spec.rb b/spec/test_link/command/get_test_suites_for_test_suite_spec.rb index d2b0bb0..0a88f2d 100644 --- a/spec/test_link/command/get_test_suites_for_test_suite_spec.rb +++ b/spec/test_link/command/get_test_suites_for_test_suite_spec.rb @@ -18,16 +18,16 @@ describe TestLink::Command::GetTestSuitesForTestSuite do it "is a command" do - TestLink::Command::GetTestSuitesForTestSuite.should < TestLink::Command::Base + expect(TestLink::Command::GetTestSuitesForTestSuite).to be < TestLink::Command::Base end it "adds a getTestSuitesForTestSuite method to TestLink::ApiLink" do - TestLink::ApiLink.new('http://qa.example.com/', '').should respond_to :getTestSuitesForTestSuite + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :getTestSuitesForTestSuite end describe 'adapter' do it 'is a TestLink::Adapters::NodeAdapter' do - TestLink::ApiLink.adapter_for(TestLink::Command::GetTestSuitesForTestSuite.command_name).should be_instance_of TestLink::Adapters::NodeAdapter + expect(TestLink::ApiLink.adapter_for(TestLink::Command::GetTestSuitesForTestSuite.command_name)).to be_instance_of TestLink::Adapters::NodeAdapter end end @@ -37,7 +37,7 @@ end it 'contain mandatory testsuiteid' do - @command.should provide_mandatory_argument :testsuiteid + expect(@command).to provide_mandatory_argument :testsuiteid end end end \ No newline at end of file diff --git a/spec/test_link/command/report_test_case_result_spec.rb b/spec/test_link/command/report_test_case_result_spec.rb new file mode 100644 index 0000000..a3411da --- /dev/null +++ b/spec/test_link/command/report_test_case_result_spec.rb @@ -0,0 +1,79 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require "test_link/command/report_test_case_result" +require "test_link/adapters/status_adapter" + +describe TestLink::Command::ReportTCResult do + it "is a command" do + expect(TestLink::Command::ReportTCResult).to be < TestLink::Command::Base + end + + it "adds a reportTCResult method to TestLink::ApiLink" do + expect(TestLink::ApiLink.new('http://qa.example.com/', '')).to respond_to :reportTCResult + end + + describe 'adapter' do + it 'is a TestLink::Adapters::StatusAdapter' do + expect(TestLink::ApiLink.adapter_for(TestLink::Command::ReportTCResult.command_name)).to be_instance_of TestLink::Adapters::StatusAdapter + end + end + + describe 'arguments' do + before :each do + @command = TestLink::Command::ReportTCResult.new + end + + it 'contain mandatory testcaseid' do + expect(@command).to provide_mandatory_argument :testcaseid + end + + it 'contain mandatory testplanid' do + expect(@command).to provide_mandatory_argument :testplanid + end + + it 'contain mandatory status' do + expect(@command).to provide_mandatory_argument :status + end + + it 'contain buildid' do + expect(@command).to provide_argument :buildid + end + + it 'contain buildname' do + expect(@command).to provide_argument :buildname + end + + it 'contain notes' do + expect(@command).to provide_argument :notes + end + + it 'contain guess' do + expect(@command).to provide_argument :bugid + end + + it 'contain platformid' do + expect(@command).to provide_argument :platformid + end + + it 'contain platformname' do + expect(@command).to provide_argument :platformname + end + + it 'contain customfields' do + expect(@command).to provide_argument :customfields + end + end +end \ No newline at end of file diff --git a/spec/test_link/enums/valid_status_list_spec.rb b/spec/test_link/enums/valid_status_list_spec.rb new file mode 100644 index 0000000..c88d4a8 --- /dev/null +++ b/spec/test_link/enums/valid_status_list_spec.rb @@ -0,0 +1,34 @@ +# This file is part of testlink-api-client. +# +# testlink-api-client is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# testlink-api-client is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with testlink-api-client. If not, see . + +require 'test_link/enums/valid_status_list' + +describe TestLink::Enums::ValidStatusList do + + before :each do + @status = TestLink::Enums::ValidStatusList + end + + it "encoding values" do + expect(@status::FAILED).to eq('f') + expect(@status::BLOCKED).to eq('b') + expect(@status::PASSED).to eq('p') + expect(@status::NOT_RUN).to eq('n') + expect(@status::NOT_AVAILABLE).to eq('x') + expect(@status::UNKNOWN).to eq('u') + expect(@status::ALL).to eq('a') + end + +end \ No newline at end of file diff --git a/spec/test_link/exceptions/command_failed_exception_spec.rb b/spec/test_link/exceptions/command_failed_exception_spec.rb index c46e113..f0ec5ec 100644 --- a/spec/test_link/exceptions/command_failed_exception_spec.rb +++ b/spec/test_link/exceptions/command_failed_exception_spec.rb @@ -22,7 +22,7 @@ describe 'message' do it 'should be "Empty response"' do - @exception.message.should == 'Command has failed: Foo message' + expect(@exception.message).to eq 'Command has failed: Foo message' end end end \ No newline at end of file diff --git a/spec/test_link/exceptions/empty_response_exception_spec.rb b/spec/test_link/exceptions/empty_response_exception_spec.rb index 3e063f8..747f97d 100644 --- a/spec/test_link/exceptions/empty_response_exception_spec.rb +++ b/spec/test_link/exceptions/empty_response_exception_spec.rb @@ -22,7 +22,7 @@ describe 'message' do it 'should be "Empty response"' do - @exception.message.should == 'Response is empty' + expect(@exception.message).to eq 'Response is empty' end end end \ No newline at end of file diff --git a/spec/test_link/exceptions/error_response_exception_spec.rb b/spec/test_link/exceptions/error_response_exception_spec.rb index 57987a4..21f9773 100644 --- a/spec/test_link/exceptions/error_response_exception_spec.rb +++ b/spec/test_link/exceptions/error_response_exception_spec.rb @@ -21,10 +21,10 @@ end it "has a code" do - @exception.should provide :code + expect(@exception).to provide :code end it "has a message" do - @exception.should respond_to :message + expect(@exception).to respond_to :message end end \ No newline at end of file diff --git a/spec/test_link/objects/node_spec.rb b/spec/test_link/objects/node_spec.rb index 38738b5..531f31b 100644 --- a/spec/test_link/objects/node_spec.rb +++ b/spec/test_link/objects/node_spec.rb @@ -20,30 +20,30 @@ end it "has an id" do - @test_suite.should provide :id + expect(@test_suite).to provide :id end it "has a parent_id" do - @test_suite.should provide :parent_id + expect(@test_suite).to provide :parent_id end it "has a type_id" do - @test_suite.should provide :type_id + expect(@test_suite).to provide :type_id end it "has a table" do - @test_suite.should provide :table + expect(@test_suite).to provide :table end it "has a name" do - @test_suite.should provide :name + expect(@test_suite).to provide :name end it "has an order" do - @test_suite.should provide :order + expect(@test_suite).to provide :order end it "has details" do - @test_suite.should provide :details + expect(@test_suite).to provide :details end end \ No newline at end of file diff --git a/spec/test_link/objects/project_spec.rb b/spec/test_link/objects/project_spec.rb index 11a8293..2eb7223 100644 --- a/spec/test_link/objects/project_spec.rb +++ b/spec/test_link/objects/project_spec.rb @@ -22,18 +22,18 @@ end it "has an id" do - @project.should provide :id + expect(@project).to provide :id end it "has a prefix" do - @project.should provide :prefix + expect(@project).to provide :prefix end it "has a name" do - @project.should provide :name + expect(@project).to provide :name end it "has notes" do - @project.should provide :notes + expect(@project).to provide :notes end end \ No newline at end of file diff --git a/spec/test_link/objects/status_spec.rb b/spec/test_link/objects/status_spec.rb index 6dca9f1..8a95a47 100644 --- a/spec/test_link/objects/status_spec.rb +++ b/spec/test_link/objects/status_spec.rb @@ -22,22 +22,22 @@ end it "has an id" do - @status.should provide :id + expect(@status).to provide :id end it "has a status" do - @status.should provide :status + expect(@status).to provide :status end it "has a message" do - @status.should provide :message + expect(@status).to provide :message end it "has an additional info" do - @status.should provide :additional_info + expect(@status).to provide :additional_info end it "refers to an operation" do - @status.should provide :operation + expect(@status).to provide :operation end end \ No newline at end of file diff --git a/testlink-api-client.gemspec b/testlink-api-client.gemspec index 47a45ce..4dc2d80 100644 --- a/testlink-api-client.gemspec +++ b/testlink-api-client.gemspec @@ -15,8 +15,8 @@ Gem::Specification.new do |spec| spec.name = 'testlink-api-client' - spec.version = '0.0.2' - spec.date = %q{2011-03-22} + spec.version = '0.0.3' + spec.date = %q{2020-04-01} spec.description = <<-EOF TestLink API Client allow to use the TestLink Remote API. EOF @@ -33,4 +33,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency('autotest-growl') spec.add_development_dependency('autotest') spec.add_development_dependency('cucumber') + spec.add_development_dependency('simplecov') end