Open snarfed opened 7 years ago
we're on python 3 now! looking forward to trying this.
done! results:
total jobs: 1113
complete: 1113 (100.00%)
survival rate: 4.49%
config file:
# https://cosmic-ray.readthedocs.io/en/latest/quickstart.html#configuration-file
module: granary
baseline: 10
exclude-modules:
- granary.test
test-runner:
name: unittest
args: granary/test/
execution-engine:
name: local
full report (debugging details in sixty-north/cosmic-ray#352):
job ID 751ca09b450d4c3b995500e7cc352e2c:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceComparisonOperator_NotIn_Is 0
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -59,7 +59,7 @@
def _activity_or_object(activity):
"Returns the base item we care about, activity or activity['object'].\n\n Used in :func:`activity_to_json()` and :func:`activities_to_html()`.\n "
- if (activity.get('object') and (activity.get('verb') not in source.VERBS_WITH_OBJECT)):
+ if (activity.get('object') and (activity.get('verb') is source.VERBS_WITH_OBJECT)):
return activity['object']
return activity
job ID d7556ddf202c43f9abffa600ade13d0c:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceOrWithAnd 7
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -70,7 +70,7 @@
obj_type = (source.object_type(obj) or default_object_type)
if (obj_type == 'post'):
primary = obj.get('object', {})
- obj_type = (source.object_type(primary) or default_object_type)
+ obj_type = (source.object_type(primary) and default_object_type)
else:
primary = obj
name = primary.get('displayName', primary.get('title'))
job ID e9f99780983f49ee824b68821814506b:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceOrWithAnd 17
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -85,7 +85,7 @@
for prop in ('attachments', 'tags'):
for elem in get_list(primary, prop):
attachments[elem.get('objectType')].append(elem)
- ret = {'type': ((AS_TO_MF2_TYPE.get(obj_type) or [entry_class]) if isinstance(entry_class, basestring) else list(entry_class)), 'properties': {'uid': [(obj.get('id') or '')], 'numeric-id': [(obj.get('numeric_id') or '')], 'name': [name], 'nickname': [(obj.get('username') or '')], 'summary': [summary], 'url': (list((object_urls(obj) or object_urls(primary))) + obj.get('upstreamDuplicates', [])), 'photo': dedupe_urls((get_urls(attachments, 'image', 'image') + get_urls(primary, 'image'))), 'video': dedupe_urls((get_urls(attachments, 'video', 'stream') + get_urls(primary, 'stream'))), 'audio': get_urls(attachments, 'audio', 'stream'), 'published': [obj.get('published', primary.get('published', ''))], 'updated': [obj.get('updated', primary.get('updated', ''))], 'content': [{'value': xml.sax.saxutils.unescape(primary.get('content', '')), 'html': render_content(primary, include_location=False, synthesize_content=synthesize_content)}], 'in-reply-to': util.trim_nulls([o.get('url') for o in in_reply_tos]), 'author': [object_to_json(author, trim_nulls=False, default_object_type='person')], 'location': [object_to_json(primary.get('location', {}), trim_nulls=False, default_object_type='place')], 'comment': [object_to_json(c, trim_nulls=False, entry_class='h-cite') for c in obj.get('replies', {}).get('items', [])], 'start': [primary.get('startTime')], 'end': [primary.get('endTime')]}, 'children': [object_to_json(a, trim_nulls=False, entry_class=['u-quotation-of', 'h-cite']) for a in (attachments['note'] + attachments['article'])]}
+ ret = {'type': ((AS_TO_MF2_TYPE.get(obj_type) or [entry_class]) if isinstance(entry_class, basestring) else list(entry_class)), 'properties': {'uid': [(obj.get('id') or '')], 'numeric-id': [(obj.get('numeric_id') or '')], 'name': [name], 'nickname': [(obj.get('username') or '')], 'summary': [summary], 'url': (list((object_urls(obj) and object_urls(primary))) + obj.get('upstreamDuplicates', [])), 'photo': dedupe_urls((get_urls(attachments, 'image', 'image') + get_urls(primary, 'image'))), 'video': dedupe_urls((get_urls(attachments, 'video', 'stream') + get_urls(primary, 'stream'))), 'audio': get_urls(attachments, 'audio', 'stream'), 'published': [obj.get('published', primary.get('published', ''))], 'updated': [obj.get('updated', primary.get('updated', ''))], 'content': [{'value': xml.sax.saxutils.unescape(primary.get('content', '')), 'html': render_content(primary, include_location=False, synthesize_content=synthesize_content)}], 'in-reply-to': util.trim_nulls([o.get('url') for o in in_reply_tos]), 'author': [object_to_json(author, trim_nulls=False, default_object_type='person')], 'location': [object_to_json(primary.get('location', {}), trim_nulls=False, default_object_type='place')], 'comment': [object_to_json(c, trim_nulls=False, entry_class='h-cite') for c in obj.get('replies', {}).get('items', [])], 'start': [primary.get('startTime')], 'end': [primary.get('endTime')]}, 'children': [object_to_json(a, trim_nulls=False, entry_class=['u-quotation-of', 'h-cite']) for a in (attachments['note'] + attachments['article'])]}
tags = (obj.get('tags', []) or get_first(obj, 'object', {}).get('tags', []))
ret['properties']['category'] = []
for tag in tags:
job ID 35e6d2407f4f4a748da02d19ec8d226b:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceTrueFalse 3
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -85,7 +85,7 @@
for prop in ('attachments', 'tags'):
for elem in get_list(primary, prop):
attachments[elem.get('objectType')].append(elem)
- ret = {'type': ((AS_TO_MF2_TYPE.get(obj_type) or [entry_class]) if isinstance(entry_class, basestring) else list(entry_class)), 'properties': {'uid': [(obj.get('id') or '')], 'numeric-id': [(obj.get('numeric_id') or '')], 'name': [name], 'nickname': [(obj.get('username') or '')], 'summary': [summary], 'url': (list((object_urls(obj) or object_urls(primary))) + obj.get('upstreamDuplicates', [])), 'photo': dedupe_urls((get_urls(attachments, 'image', 'image') + get_urls(primary, 'image'))), 'video': dedupe_urls((get_urls(attachments, 'video', 'stream') + get_urls(primary, 'stream'))), 'audio': get_urls(attachments, 'audio', 'stream'), 'published': [obj.get('published', primary.get('published', ''))], 'updated': [obj.get('updated', primary.get('updated', ''))], 'content': [{'value': xml.sax.saxutils.unescape(primary.get('content', '')), 'html': render_content(primary, include_location=False, synthesize_content=synthesize_content)}], 'in-reply-to': util.trim_nulls([o.get('url') for o in in_reply_tos]), 'author': [object_to_json(author, trim_nulls=False, default_object_type='person')], 'location': [object_to_json(primary.get('location', {}), trim_nulls=False, default_object_type='place')], 'comment': [object_to_json(c, trim_nulls=False, entry_class='h-cite') for c in obj.get('replies', {}).get('items', [])], 'start': [primary.get('startTime')], 'end': [primary.get('endTime')]}, 'children': [object_to_json(a, trim_nulls=False, entry_class=['u-quotation-of', 'h-cite']) for a in (attachments['note'] + attachments['article'])]}
+ ret = {'type': ((AS_TO_MF2_TYPE.get(obj_type) or [entry_class]) if isinstance(entry_class, basestring) else list(entry_class)), 'properties': {'uid': [(obj.get('id') or '')], 'numeric-id': [(obj.get('numeric_id') or '')], 'name': [name], 'nickname': [(obj.get('username') or '')], 'summary': [summary], 'url': (list((object_urls(obj) or object_urls(primary))) + obj.get('upstreamDuplicates', [])), 'photo': dedupe_urls((get_urls(attachments, 'image', 'image') + get_urls(primary, 'image'))), 'video': dedupe_urls((get_urls(attachments, 'video', 'stream') + get_urls(primary, 'stream'))), 'audio': get_urls(attachments, 'audio', 'stream'), 'published': [obj.get('published', primary.get('published', ''))], 'updated': [obj.get('updated', primary.get('updated', ''))], 'content': [{'value': xml.sax.saxutils.unescape(primary.get('content', '')), 'html': render_content(primary, include_location=False, synthesize_content=synthesize_content)}], 'in-reply-to': util.trim_nulls([o.get('url') for o in in_reply_tos]), 'author': [object_to_json(author, trim_nulls=True, default_object_type='person')], 'location': [object_to_json(primary.get('location', {}), trim_nulls=False, default_object_type='place')], 'comment': [object_to_json(c, trim_nulls=False, entry_class='h-cite') for c in obj.get('replies', {}).get('items', [])], 'start': [primary.get('startTime')], 'end': [primary.get('endTime')]}, 'children': [object_to_json(a, trim_nulls=False, entry_class=['u-quotation-of', 'h-cite']) for a in (attachments['note'] + attachments['article'])]}
tags = (obj.get('tags', []) or get_first(obj, 'object', {}).get('tags', []))
ret['properties']['category'] = []
for tag in tags:
job ID 679f16baadaf4a6aa8bf9f80df1381a0:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceTrueFalse 4
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -85,7 +85,7 @@
for prop in ('attachments', 'tags'):
for elem in get_list(primary, prop):
attachments[elem.get('objectType')].append(elem)
- ret = {'type': ((AS_TO_MF2_TYPE.get(obj_type) or [entry_class]) if isinstance(entry_class, basestring) else list(entry_class)), 'properties': {'uid': [(obj.get('id') or '')], 'numeric-id': [(obj.get('numeric_id') or '')], 'name': [name], 'nickname': [(obj.get('username') or '')], 'summary': [summary], 'url': (list((object_urls(obj) or object_urls(primary))) + obj.get('upstreamDuplicates', [])), 'photo': dedupe_urls((get_urls(attachments, 'image', 'image') + get_urls(primary, 'image'))), 'video': dedupe_urls((get_urls(attachments, 'video', 'stream') + get_urls(primary, 'stream'))), 'audio': get_urls(attachments, 'audio', 'stream'), 'published': [obj.get('published', primary.get('published', ''))], 'updated': [obj.get('updated', primary.get('updated', ''))], 'content': [{'value': xml.sax.saxutils.unescape(primary.get('content', '')), 'html': render_content(primary, include_location=False, synthesize_content=synthesize_content)}], 'in-reply-to': util.trim_nulls([o.get('url') for o in in_reply_tos]), 'author': [object_to_json(author, trim_nulls=False, default_object_type='person')], 'location': [object_to_json(primary.get('location', {}), trim_nulls=False, default_object_type='place')], 'comment': [object_to_json(c, trim_nulls=False, entry_class='h-cite') for c in obj.get('replies', {}).get('items', [])], 'start': [primary.get('startTime')], 'end': [primary.get('endTime')]}, 'children': [object_to_json(a, trim_nulls=False, entry_class=['u-quotation-of', 'h-cite']) for a in (attachments['note'] + attachments['article'])]}
+ ret = {'type': ((AS_TO_MF2_TYPE.get(obj_type) or [entry_class]) if isinstance(entry_class, basestring) else list(entry_class)), 'properties': {'uid': [(obj.get('id') or '')], 'numeric-id': [(obj.get('numeric_id') or '')], 'name': [name], 'nickname': [(obj.get('username') or '')], 'summary': [summary], 'url': (list((object_urls(obj) or object_urls(primary))) + obj.get('upstreamDuplicates', [])), 'photo': dedupe_urls((get_urls(attachments, 'image', 'image') + get_urls(primary, 'image'))), 'video': dedupe_urls((get_urls(attachments, 'video', 'stream') + get_urls(primary, 'stream'))), 'audio': get_urls(attachments, 'audio', 'stream'), 'published': [obj.get('published', primary.get('published', ''))], 'updated': [obj.get('updated', primary.get('updated', ''))], 'content': [{'value': xml.sax.saxutils.unescape(primary.get('content', '')), 'html': render_content(primary, include_location=False, synthesize_content=synthesize_content)}], 'in-reply-to': util.trim_nulls([o.get('url') for o in in_reply_tos]), 'author': [object_to_json(author, trim_nulls=False, default_object_type='person')], 'location': [object_to_json(primary.get('location', {}), trim_nulls=True, default_object_type='place')], 'comment': [object_to_json(c, trim_nulls=False, entry_class='h-cite') for c in obj.get('replies', {}).get('items', [])], 'start': [primary.get('startTime')], 'end': [primary.get('endTime')]}, 'children': [object_to_json(a, trim_nulls=False, entry_class=['u-quotation-of', 'h-cite']) for a in (attachments['note'] + attachments['article'])]}
tags = (obj.get('tags', []) or get_first(obj, 'object', {}).get('tags', []))
ret['properties']['category'] = []
for tag in tags:
job ID 85b5f2c644634774a78d5ff3609c17c7:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceTrueFalse 7
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -98,7 +98,7 @@
if is_rsvp:
ret['properties']['rsvp'] = [obj_type[len('rsvp-'):]]
elif (obj_type == 'invite'):
- invitee = object_to_json(obj.get('object'), trim_nulls=False, default_object_type='person')
+ invitee = object_to_json(obj.get('object'), trim_nulls=True, default_object_type='person')
ret['properties']['invitee'] = [invitee]
for (type, prop) in (('favorite', 'like'), ('like', 'like'), ('share', 'repost')):
if (obj_type == type):
job ID 3e8b31cbe0d741859fa95a44e59d6f9f:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceTrueFalse 8
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -103,7 +103,7 @@
for (type, prop) in (('favorite', 'like'), ('like', 'like'), ('share', 'repost')):
if (obj_type == type):
objs = get_list(obj, 'object')
- ret['properties'][(prop + '-of')] = [(o['url'] if (('url' in o) and (set(o.keys()) <= set(['url', 'objectType']))) else object_to_json(o, trim_nulls=False, entry_class='h-cite')) for o in objs]
+ ret['properties'][(prop + '-of')] = [(o['url'] if (('url' in o) and (set(o.keys()) <= set(['url', 'objectType']))) else object_to_json(o, trim_nulls=True, entry_class='h-cite')) for o in objs]
else:
ret['properties'][prop] = [object_to_json(t, trim_nulls=False, entry_class='h-cite') for t in tags if (source.object_type(t) == type)]
lat = long = None
job ID bea1deff4cf04359a51bf38d07b43467:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceComparisonOperator_In_IsNot 1
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -103,7 +103,7 @@
for (type, prop) in (('favorite', 'like'), ('like', 'like'), ('share', 'repost')):
if (obj_type == type):
objs = get_list(obj, 'object')
- ret['properties'][(prop + '-of')] = [(o['url'] if (('url' in o) and (set(o.keys()) <= set(['url', 'objectType']))) else object_to_json(o, trim_nulls=False, entry_class='h-cite')) for o in objs]
+ ret['properties'][(prop + '-of')] = [(o['url'] if (('url' is not o) and (set(o.keys()) <= set(['url', 'objectType']))) else object_to_json(o, trim_nulls=False, entry_class='h-cite')) for o in objs]
else:
ret['properties'][prop] = [object_to_json(t, trim_nulls=False, entry_class='h-cite') for t in tags if (source.object_type(t) == type)]
lat = long = None
job ID ed97ceb5bb09489f82aceb27ff0f09ca:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceTrueFalse 9
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -105,7 +105,7 @@
objs = get_list(obj, 'object')
ret['properties'][(prop + '-of')] = [(o['url'] if (('url' in o) and (set(o.keys()) <= set(['url', 'objectType']))) else object_to_json(o, trim_nulls=False, entry_class='h-cite')) for o in objs]
else:
- ret['properties'][prop] = [object_to_json(t, trim_nulls=False, entry_class='h-cite') for t in tags if (source.object_type(t) == type)]
+ ret['properties'][prop] = [object_to_json(t, trim_nulls=True, entry_class='h-cite') for t in tags if (source.object_type(t) == type)]
lat = long = None
position = ISO_6709_RE.match((primary.get('position') or ''))
if position:
job ID 3db7d4456a9d4941b26e5abc0830d322:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceOrWithAnd 23
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -124,7 +124,7 @@
def json_to_object(mf2, actor=None, fetch_mf2=False):
'Converts microformats2 JSON to an ActivityStreams object.\n\n Args:\n mf2: dict, decoded JSON microformats2 object\n actor: optional author AS actor object. usually comes from a rel="author"\n link. if mf2 has its own author, that will override this.\n fetch_mf2: boolean, whether to fetch additional pages via HTTP if necessary,\n e.g. to determine authorship: https://indieweb.org/authorship\n\n Returns:\n dict, ActivityStreams object\n '
- if ((not mf2) or (not isinstance(mf2, dict))):
+ if ((not mf2) and (not isinstance(mf2, dict))):
return {}
mf2 = copy.copy(mf2)
props = mf2.setdefault('properties', {})
job ID d3ee375384ce4a9eb3d2410628e10d5a:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ZeroIterationLoop 4
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -153,7 +153,7 @@
if rsvp:
as_verb = ('rsvp-%s' % rsvp)
in_reply_tos = get_string_urls(props.get('in-reply-to', []))
- for url in in_reply_tos:
+ for url in []:
if re.match('^https?://github.com/[^/]+/[^/]+(/issues)?/?$', url):
as_type = 'issue'
job ID b66c3d4a386249de95b4700fefde8f68:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceComparisonOperator_In_IsNot 4
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -160,7 +160,7 @@
def absolute_urls(prop):
return [url for url in get_string_urls(props.get(prop, [])) if urllib.parse.urlparse(url).netloc]
urls = (props.get('url') and get_string_urls(props.get('url')))
- attachments = [json_to_object(quote) for quote in (mf2.get('children', []) + props.get('quotation-of', [])) if (isinstance(quote, dict) and ('h-cite' in set(quote.get('type', []))))]
+ attachments = [json_to_object(quote) for quote in (mf2.get('children', []) + props.get('quotation-of', [])) if (isinstance(quote, dict) and ('h-cite' is not set(quote.get('type', []))))]
for type in ('audio', 'video'):
attachments.extend(({'objectType': type, 'stream': {'url': url}} for url in get_string_urls(props.get(type, []))))
obj = {'id': prop.get('uid'), 'objectType': as_type, 'verb': as_verb, 'published': prop.get('published', ''), 'updated': prop.get('updated', ''), 'startTime': prop.get('start'), 'endTime': prop.get('end'), 'displayName': get_text(prop.get('name')), 'summary': get_text(prop.get('summary')), 'content': get_html(prop.get('content')), 'url': (urls[0] if urls else None), 'urls': ([{'value': u} for u in urls] if (urls and (len(urls) > 1)) else None), 'image': [{'url': url} for url in dedupe_urls((absolute_urls('photo') + absolute_urls('featured')))], 'stream': [{'url': url} for url in absolute_urls('video')], 'location': json_to_object(prop.get('location')), 'replies': {'items': [json_to_object(c) for c in props.get('comment', [])]}, 'tags': [({'objectType': 'hashtag', 'displayName': cat} if isinstance(cat, basestring) else json_to_object(cat)) for cat in props.get('category', [])], 'attachments': attachments}
job ID 172cd68866ba4dbea3ed75084b42fc08:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceComparisonOperator_Gt_NotEq 0
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -163,7 +163,7 @@
attachments = [json_to_object(quote) for quote in (mf2.get('children', []) + props.get('quotation-of', [])) if (isinstance(quote, dict) and ('h-cite' in set(quote.get('type', []))))]
for type in ('audio', 'video'):
attachments.extend(({'objectType': type, 'stream': {'url': url}} for url in get_string_urls(props.get(type, []))))
- obj = {'id': prop.get('uid'), 'objectType': as_type, 'verb': as_verb, 'published': prop.get('published', ''), 'updated': prop.get('updated', ''), 'startTime': prop.get('start'), 'endTime': prop.get('end'), 'displayName': get_text(prop.get('name')), 'summary': get_text(prop.get('summary')), 'content': get_html(prop.get('content')), 'url': (urls[0] if urls else None), 'urls': ([{'value': u} for u in urls] if (urls and (len(urls) > 1)) else None), 'image': [{'url': url} for url in dedupe_urls((absolute_urls('photo') + absolute_urls('featured')))], 'stream': [{'url': url} for url in absolute_urls('video')], 'location': json_to_object(prop.get('location')), 'replies': {'items': [json_to_object(c) for c in props.get('comment', [])]}, 'tags': [({'objectType': 'hashtag', 'displayName': cat} if isinstance(cat, basestring) else json_to_object(cat)) for cat in props.get('category', [])], 'attachments': attachments}
+ obj = {'id': prop.get('uid'), 'objectType': as_type, 'verb': as_verb, 'published': prop.get('published', ''), 'updated': prop.get('updated', ''), 'startTime': prop.get('start'), 'endTime': prop.get('end'), 'displayName': get_text(prop.get('name')), 'summary': get_text(prop.get('summary')), 'content': get_html(prop.get('content')), 'url': (urls[0] if urls else None), 'urls': ([{'value': u} for u in urls] if (urls and (len(urls) != 1)) else None), 'image': [{'url': url} for url in dedupe_urls((absolute_urls('photo') + absolute_urls('featured')))], 'stream': [{'url': url} for url in absolute_urls('video')], 'location': json_to_object(prop.get('location')), 'replies': {'items': [json_to_object(c) for c in props.get('comment', [])]}, 'tags': [({'objectType': 'hashtag', 'displayName': cat} if isinstance(cat, basestring) else json_to_object(cat)) for cat in props.get('category', [])], 'attachments': attachments}
interpreted = mf2util.interpret({'items': [mf2]}, None)
if interpreted:
loc = interpreted.get('location')
job ID a8b4c90581bc44d287f79e93a13f93b3:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceAndWithOr 17
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -170,7 +170,7 @@
if loc:
obj['location']['objectType'] = 'place'
(lat, lng) = (loc.get('latitude'), loc.get('longitude'))
- if (lat and lng):
+ if (lat or lng):
try:
obj['location'].update({'latitude': float(lat), 'longitude': float(lng)})
except ValueError:
job ID 54b8ee2910ef40728186a90d4353dec3:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceComparisonOperator_NotIn_NotEq 1
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -179,7 +179,7 @@
objects = []
for target in itertools.chain.from_iterable((props.get(field, []) for field in ('like', 'like-of', 'repost', 'repost-of', 'in-reply-to', 'invitee'))):
t = (json_to_object(target) if isinstance(target, dict) else {'url': target})
- if (t not in objects):
+ if (t != objects):
objects.append(t)
obj.update({'object': (objects[0] if (len(objects) == 1) else objects), 'actor': author})
else:
job ID b37d3abbb2ae4f7eaf5f06756984163c:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/NumberReplacer 15
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -230,7 +230,7 @@
if rsvp:
if (not props.get('name')):
props['name'] = [{'yes': 'is attending.', 'no': 'is not attending.', 'maybe': 'might attend.'}.get(rsvp)]
- props['name'][0] = ('<data class="p-rsvp" value="%s">%s</data>' % (rsvp, props['name'][0]))
+ props['name'][0] = ('<data class="p-rsvp" value="%s">%s</data>' % (rsvp, props['name'][-1]))
elif (props.get('invitee') and (not props.get('name'))):
props['name'] = ['invited']
children = []
job ID e213bc5b5c0741cebb8d70925ebecae0:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceComparisonOperator_NotIn_IsNot 2
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -257,7 +257,7 @@
tags = [('<span class="u-category">%s</span>' % cat) for cat in cats if isinstance(cat, basestring)]
comments_html = '\n'.join((json_to_html(c, ['p-comment']) for c in props.get('comment', [])))
for verb in ('like', 'repost'):
- if ((verb + '-of') not in props):
+ if ((verb + '-of') is not props):
vals = props.get(verb, [])
if (vals and isinstance(vals[0], dict)):
children += [json_to_html(v, [('u-' + verb)]) for v in vals]
job ID 6a005e48360c40469beb7b67a7ed1432:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/NumberReplacer 17
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -259,7 +259,7 @@
for verb in ('like', 'repost'):
if ((verb + '-of') not in props):
vals = props.get(verb, [])
- if (vals and isinstance(vals[0], dict)):
+ if (vals and isinstance(vals[-1], dict)):
children += [json_to_html(v, [('u-' + verb)]) for v in vals]
children += [json_to_html(c) for c in obj.get('children', [])]
location = prop.get('location')
job ID 6fde419f4bdb4c38a2433e5e2234ed46:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceAndWithOr 26
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -269,7 +269,7 @@
start = props.get('start', [])
end = props.get('end', [])
event_times += [(' <time class="dt-start">%s</time>' % time) for time in start]
- if (start and end):
+ if (start or end):
event_times.append(' to')
event_times += [(' <time class="dt-end">%s</time>' % time) for time in end]
return HENTRY.substitute(prop, published=maybe_datetime(prop.get('published'), 'dt-published'), updated=maybe_datetime(prop.get('updated'), 'dt-updated'), types=' '.join((parent_props + types)), author=hcard_to_html(author, ['p-author']), location=hcard_to_html(location, ['p-location']), categories='\n'.join((people + tags)), attachments='\n'.join(attachments), in_reply_tos=in_reply_tos, invitees='\n'.join([hcard_to_html(i, ['p-invitee']) for i in props.get('invitee', [])]), content=content_html, content_classes=' '.join(content_classes), comments=comments_html, children='\n'.join(children), linked_name=maybe_linked_name(props), summary=summary, event_times='\n'.join(event_times))
job ID be1f8761dfde4dceb145500ac49be72a:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceAndWithOr 30
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -297,7 +297,7 @@
if (id and (id in seen_ids)):
continue
seen_ids.add(id)
- if (('startIndex' in t) and ('length' in t)):
+ if (('startIndex' in t) or ('length' in t)):
mentions.append(t)
else:
tags.setdefault(source.object_type(t), []).append(t)
job ID 4814bb601a3b428d957a7c2069646e26:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceComparisonOperator_NotIn_Is 4
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -319,7 +319,7 @@
content += _render_attachments((atts + tags.pop('article', [])), obj)
obj_type = source.object_type(obj)
for (as_type, verb) in (('favorite', 'Favorites'), ('like', 'Likes'), ('share', 'Shared')):
- if ((not synthesize_content) or (obj_type != as_type) or ('object' not in obj) or ('content' in obj)):
+ if ((not synthesize_content) or (obj_type != as_type) or ('object' is obj) or ('content' in obj)):
continue
targets = get_list(obj, 'object')
if (not targets):
job ID 48bf3f011a2b49ea9ef878badcc179c9:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceBinaryOperator_Mod_Add 11
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -330,7 +330,7 @@
else:
author = target.get('author', target.get('actor', {}))
if ((obj_type == 'share') and ('url' in obj) and re.search('^https?://(?:www\\.|mobile\\.)?twitter\\.com/', obj.get('url'))):
- content += ('RT <a href="%s">@%s</a> ' % (target.get('url', '#'), author.get('username')))
+ content += ('RT <a href="%s">@%s</a> ' + (target.get('url', '#'), author.get('username')))
else:
author = {k: v for (k, v) in author.items() if (k != 'image')}
content += ('%s <a href="%s">%s</a> by %s' % (verb, target.get('url', '#'), target.get('displayName', target.get('title', 'a post')), hcard_to_html(object_to_json(author, default_object_type='person'))))
job ID 62cb22b52f6b4fa9a40e5afa849797b9:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/ReplaceComparisonOperator_NotIn_NotEq 5
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -338,7 +338,7 @@
break
break
if (render_attachments and (obj.get('verb') == 'share')):
- atts = [a for a in obj.get('object', {}).get('attachments', []) if (a.get('objectType') not in ('note', 'article'))]
+ atts = [a for a in obj.get('object', {}).get('attachments', []) if (a.get('objectType') != ('note', 'article'))]
content += _render_attachments(atts, obj)
loc = obj.get('location')
if (include_location and loc):
job ID a5b47eec08e346d4800919a1848cc750:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/AddNot 61
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -410,7 +410,7 @@
def author_display_name(hcard):
'Returns a human-readable string display name for an h-card object.'
name = None
- if hcard:
+ if (not hcard):
prop = first_props(hcard.get('properties'))
name = (prop.get('name') or prop.get('uid'))
return (name if name else 'Unknown')
job ID 0dbd3d16692043f89d7e66971ea5f39b:survived:granary.microformats2
command: cosmic-ray worker granary.microformats2 core/AddNot 62
--- mutation diff ---
--- a/Users/ryan/src/granary/granary/microformats2.py
+++ b/Users/ryan/src/granary/granary/microformats2.py
@@ -413,7 +413,7 @@
if hcard:
prop = first_props(hcard.get('properties'))
name = (prop.get('name') or prop.get('uid'))
- return (name if name else 'Unknown')
+ return (name if (not name) else 'Unknown')
def maybe_linked_name(props):
'Returns the HTML for a p-name with an optional u-url inside.\n\n Args:\n props: *multiply-valued* properties dict\n\n Returns:\n string HTML\n '
total jobs: 1113
complete: 1113 (100.00%)
survival rate: 4.49%
i also tried to do this for https://github.com/snarfed/webutil , but got stuck since only util.py
is python 3, and the cosmic-ray config lets me run a specific directory's tests, but not a specific file. (i got it running, but it reported that almost all mutants survived, which they didn't.)
the fix would be to add a new cosmic ray config option and pass it to TestLoader.discover()
here.
i skimmed the granary mutations. they generally all look real, but not high priority, so i'm deprioritizing adding tests for them, at least for now.
...also i expect granary's cosmic ray config is buggy too, since we only got mutant reports in microformats2.py
, no other files.
...via something like https://github.com/sixty-north/cosmic-ray. mutation testing is very cool. description in https://cosmic-ray.readthedocs.io/en/latest/#theory
long pole is that cosmic ray is python 3 only, which implies that this depends on #114. sixty-north/cosmic-ray#101 has more details about cosmic ray's lack of python 2 support.