RSpec Mark Failed Tests as Skipped - ruby-on-rails-4

We have a unit test suite, written in RSpec. We have some failed tests that is a lot actually.
What I am looking for is a script or a magic command, to mark all the failed tests as skipped, so I don't have to go over them one by one and mark them as skipped.

I found this awesome script that do exactly what I need:
https://gist.github.com/mcoms/77954d191bde31d4677872d2ab3d0cd5
Copying the contents here, in case the original gist is deleted:
# frozen_string_literal: true
class CustomFormatter
RSpec::Core::Formatters.register self, :example_failed
def initialize(output)
#output = output
end
def example_failed(notification)
tf = Tempfile.new
File.open(notification.example.metadata[:file_path]) do |f|
counter = 1
while (line = f.gets)
if counter == notification.example.metadata[:line_number]
line.sub!('it', 'skip')
line.sub!('scenario', 'skip')
#output << line
end
tf.write line
counter += 1
end
end
tf.close
FileUtils.mv tf.path, notification.example.metadata[:file_path]
end
end

Should be relatively straightforward. RSpec lists failing specs like this
rspec ./spec/models/user.rb:67 # User does this thing
rspec ./spec/models/post.rb:13 # Post does another thing
rspec ./spec/models/rating.rb:123 # Rating does something else entirely
File name and line number point to the opening line of the test, the one with it ... do.
Write a script that
extracts file names and line numbers from the failure output
opens those files, goes to the specified line
and replaces it with xit.

Related

GitPython: How can I access the contents of a file in a commit in GitPython

I am new to GitPython and I am trying to get the content of a file within a commit. I am able to get each file from a specific commit, but I am getting an error each time I run the command. Now, I know that the file exist in GitPython, but each time I run my program, I am getting the following error:
returned non-zero exit status 1
I am using Python 2.7.6 and Ubuntu Linux 14.04.
I know that the file exist, since I also go directly into Git from the command line, check out the respective commit, search for the file, and find it. I also run the cat command on it, and the file contents are displayed. Many times when the error shows up, it says that the file in question does not exist. I am trying to go through each commit with GitPython, get every blob or file from each individual commit, and run an external Java program on the content of that file. The Java program is designed to return a string to Python. To capture the string returned from my Java code, I am also using subprocess.check_output. Any help will be greatly appreciated.
I tried passing in the command as a list:
cmd = ['java', '-classpath', '/home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*:', 'java_gram.mainJava','absolute/path/to/file']
subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
And I have also tried passing the command as a string:
subprocess.check_output('java -classpath /home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*: java_gram.mainJava {file}'.format(file=entry.abspath.strip()), shell=True)
Is it possible to access the contents of a file from GitPython?
For example, say there is a commit and it has one file foo.java
In that file is the following lines of code:
foo.java
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class foo{
public static void main(String[] args) throws Exception{}
}
I want to access everything in the file and run an external program on it.
Any help would be greatly appreciated. Below is a piece of the code I am using to do so
#! usr/bin/env python
__author__ = 'rahkeemg'
from git import *
import git, json, subprocess, re
git_dir = '/home/rahkeemg/Documents/GitRepositories/WhereHows'
# make an instance of the repository from specified path
repo = Repo(path=git_dir)
heads = repo.heads # obtain the different repositories
master = heads.master # get the master repository
print master
# get all of the commits on the master branch
commits = list(repo.iter_commits(master))
cmd = ['java', '-classpath', '/home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*:', 'java_gram.mainJava']
# start at the very 1st commit, or start at commit 0
for i in range(len(commits) - 1, 0, -1):
commit = commits[i]
commit_num = len(commits) - 1 - i
print commit_num, ": ", commit.hexsha, '\n', commit.message, '\n'
for entry in commit.tree.traverse():
if re.search(r'\.java', entry.path):
current_file = str(entry.abspath.strip())
# add the current file or blob to the list for the command to run
cmd.append(current_file)
print entry.abspath
try:
# This is the scenario where I pass arguments into command as a string
print subprocess.check_output('java -classpath /home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*: java_gram.mainJava {file}'.format(file=entry.abspath.strip()), shell=True)
# scenario where I pass arguments into command as a list
j_response = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
except subprocess.CalledProcessError as e:
print "Error on file: ", current_file
# Use pop on list to remove the last string, which is the selected file at the moment, to make place for the next file.
cmd.pop()
First of all, when you traverse the commit history like this, the file will not be checked out. All you get is the filename, maybe leading to the file or maybe not, but certainly it will not lead to the file from different revision than currently checked-out.
However, there is a solution to this. Remember that in principle, anything you could do with some git command, you can do with GitPython.
To get file contents from specific revision, you can do the following, which I've taken from that page:
git show <treeish>:<file>
therefore, in GitPython:
file_contents = repo.git.show('{}:{}'.format(commit.hexsha, entry.path))
However, that still wouldn't make the file appear on disk. If you need some real path for the file, you can use tempfile:
f = tempfile.NamedTemporaryFile(delete=False)
f.write(file_contents)
f.close()
# at this point file with name f.name contains contents of
# the file from path entry.path at revision commit.hexsha
# your program launch goes here, use f.name as filename to be read
os.unlink(f.name) # delete the temp file

Python: Returning a filename for matching a specific condition

import sys, hashlib
import os
inputFile = 'C:\Users\User\Desktop\hashes.txt'
sourceDir = 'C:\Users\User\Desktop\Test Directory'
hashMatch = False
for root, dirs, files in os.walk(sourceDir):
for filename in files:
sourceDirHashes = hashlib.md5(filename)
for digest in inputFile:
if sourceDirHashes.hexdigest() == digest:
hashMatch = True
break
if hashMatch:
print str(filename)
else:
print 'hash not found'
Contents of inputFile =
2899ebdb5f7a90a216e97b3187851fc1
54c177418615a90a6424cb945f7a6aec
dd18bf3a8e0a2a3e53e2661c7fb53534
Contents of sourceDir files =
test
test 1
test 2
I almost have the code working, I'm just tripping up somewhere. My current code that I have posted always returns the else statement, that the hash hasn't been found, even although they do as I have verified this. I have provided the content of my sourceDir so that someone case try this, the file names are test, test 1 and test 2, the same content is in the files.
I must add however, I am not looking for the script to print the actual file content, but rather the name of the file.
Could anyone suggest to where I am going wrong and why it is saying the condition is false?
You need to open the inputFile using open(inputFile, 'rt') then you can read the hashes. Also when you do read the hashes make sure you strip them first to get rid of new line characters \n at the end of the lines

Use whenever gem to setup a cron job

I want to setup a cron job to delete screenshots which are older than two minutes and the cron job to run every two minutes.
Contents of schedule.rb file
every 2.minutes do
runner 'screenshot.delete_old', output: {error: "#{path}/log/error.log", standard: "#{path}/log/cron.log"}
end
Contents of Model Screenshot.rb file
def self.delete_old
# #old_screenshots = Screenshot.where('Screenshot.created_at < ?', Time.now)
##old_screenshots.delete_all
##screenshot.delete_old
#Screenshot.delete
screenshot_ids = screenshot.find(:all, :conditions => ["created_at ", 2.minutes.ago])
if screenshot_ids.size > 0
screenshot.destroy(screenshot_ids)
puts "#{screenshot_ids.size} screenshots have been deleted!"
end
end
I updated the crontab file and ran the rails server expecting the screeshots to be deleted. But it is not working. Could someone help me with this? Thanks.
Classes in Ruby should have capital first letter, maybe you should try:
every 2.minutes do
runner 'Screenshot.delete_old', output: {error: "#{path}/log/error.log", standard: "#{path}/log/cron.log"}
end
and your model:
def self.delete_old
screenshot_ids = Screenshot.where('created_at < ?', 2.minutes.ago))
if screenshot_ids.size > 0
Screenshot.destroy(screenshot_ids)
puts "#{screenshot_ids.size} screenshots have been deleted!"
end
end

Carrierwave Multiple File Upload + No implicit conversion of nil into String

Trying to get Carrierwave multiple file uploads working. I'm following the documentation on the homepage. When I try to upload a file or multiple, I get an no implicit conversion of nil to string
That error is coming from this method in the Carrierwave gem found in uploaders/cache.rb
def workfile_path(for_file=original_filename)
File.join(CarrierWave.tmp_path, #cache_id, version_name.to_s, for_file)
end
The issue is that the original_file is nil. I've tried to trace the issue but can't find where the issue is really beginning. One thing that is odd is that I am following some source code from this repo
https://github.com/bobintornado/sample-gallery-app-with-carrierwave
The sample app is working and you can do multiple uploads. The difference though is that when cache! method is called the new_file is an Array where in sample app that's working it's Http::UploadedFile
Here's the cache method
def cache!(new_file = sanitized_file)
new_file = CarrierWave::SanitizedFile.new(new_file)
return if new_file.empty?
raise CarrierWave::FormNotMultipart if new_file.is_path? && ensure_multipart_form
self.cache_id = CarrierWave.generate_cache_id unless cache_id
#filename = new_file.filename
self.original_filename = new_file.filename
begin
# first, create a workfile on which we perform processings
if move_to_cache
#file = new_file.move_to(File.expand_path(workfile_path, root), permissions, directory_permissions)
else
#file = new_file.copy_to(File.expand_path(workfile_path, root), permissions, directory_permissions)
end
with_callbacks(:cache, #file) do
#file = cache_storage.cache!(#file)
end
ensure
FileUtils.rm_rf(workfile_path(''))
end
end
Here are my initial params
"coach"=>{"name"=>"ben", "title"=>"ceo", "description"=>"head dude",
"photos"=>[
#<ActionDispatch::Http::UploadedFile:0x007fc9a5235c78 #tempfile=#<Tempfile:/var/folders/sb/t6rry5j928l3sy96nkhy9f840000gn/T/RackMultipart20160113-67635-avg8ef.jpg>, #original_filename="benn-1.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"coach[photos][]\"; filename=\"benn-1.jpg\"\r\nContent-Type: image/jpeg\r\n">,
#<ActionDispatch::Http::UploadedFile:0x007fc9a5235c50 #tempfile=#<Tempfile:/var/folders/sb/t6rry5j928l3sy96nkhy9f840000gn/T/RackMultipart20160113-67635-r8bdxp.jpg>, #original_filename="benn-2.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"coach[photos][]\"; filename=\"benn-2.jpg\"\r\nContent-Type: image/jpeg\r\n">
]}
Sorry this isn't terribly helpful, but I burned my current working branch and started from the beginning and now everything is working. Not sure what I did differently. If you're running into the same issue I recommend starting over and following this tutorial:
Multiple-Images-Uploading-With-CarrierWave-and-PostgreSQL-Array

How to replace string in multiple files in the folder?

I m trying to read two files and replace content of one file with content of other file in files present in folder which also has sub directories.
But its tell sub process not defined.
i'm new to python and shell script can anybody help me with this please?
import os
import sys
import os.path
f = open ( "file1.txt",'r')
g = open ( "file2.txt",'r')
text1=f.readlines()
text2=g.readlines()
i = 0;
for line in text1:
l = line.replace("\r\n", "")
t = text2[i].replace("\r\n", "")
args = "find . -name *.tml"
Path = subprocess.Popen( args , shell=True )
os.system(" sed -r -i 's/" + l + "/" + t + "/g' " + Path)
i = i + 1;
To specifically address your actual error, you need to import the subprocess module as you are making use of it (oddly) in your code:
import subprocess
After that, you will find more problems. I will try and keep it as simple as possible with my suggestions. Code first, then I will break it down. Keep in mind, there are more robust ways to accomplish this task. But I am doing my best to keep in mind your experience level and making it make your current approach as closely as possible.
import subprocess
import sys
# 1
results = subprocess.Popen("find . -name '*.tml'",
shell=True, stdout=subprocess.PIPE)
if results.wait() != 0:
print "error trying to find tml files"
sys.exit(1)
# 2
tml_files = []
for tml in results.stdout:
tml_files.append(tml.strip())
if not tml_files:
print "no tml files found"
sys.exit(0)
tml_string = " ".join(tml_files)
# 3
with open ("file1.txt") as f, open("file2.txt") as g:
while True:
# 4
f_line = f.readline()
if not f_line:
break
g_line = g.readline()
if not g_line:
break
f_line = f_line.strip()
g_line = g_line.strip()
if not f_line or not g_line:
continue
# 5
cmd = "sed -i -e 's/%s/%s/g' %s" % \
(f_line.strip(), g_line.strip(), tml_string)
ret = subprocess.Popen(cmd, shell=True).wait()
if ret != 0:
print "error doing string replacement"
sys.exit(1)
You do not need to read in your entire files at once. If they are large this could be a lot of memory. You can consume a line at a time, and you can also make use of what is called "context managers" when you open the files. This will ensure they close properly no matter what happens:
We start with a subprocess command that is run only once to find all your .tml files. Your version had the same command being run multiple times. If the search path is the same, then we only need it once. This checks the exit code of the command and quits if it failed.
We loop over stdout on the subprocess command, and add the stripped lines to a list. This is a more robust way of your replace("\r\n"). It removes whitespace. A "list comprehension" would be better suited here (down the line). If we didn't find any tml files, then we have no work to do, so we exit. Otherwise, we join them together in a space-separated string to be suitable for our command later.
This is called "context managers". You can open the file in a way that no matter what they will be closed properly. The file is open for the length of the context within that code block. We are going to loop forever, and break when appropriate.
We pull a line, one at a time, from each file. If either line is blank, we reached the end of the file and cannot do any more work, so we break out. We then strip the newlines, and if either string is empty (blank line) we still can't do any work, but we just continue to the next available line.
A modified version of your sed command. We construct the command string on each loop for the source and replacement strings, and tack on the tml file string. Bear in mind this is a very naive approach to the replacement. It really expects your replacement strings to be safe characters and not break the s///g sed format. But we run that with another subprocess command. The wait() simply waits for the return code, and we check it for an error. This approach replaces your os.system() version.
Hope this helps. Eventually you can improve this to do more checking and safe operations.