aboutsummaryrefslogtreecommitdiffstats
path: root/libccnx-common/ccnx/common/test
diff options
context:
space:
mode:
Diffstat (limited to 'libccnx-common/ccnx/common/test')
-rw-r--r--libccnx-common/ccnx/common/test/.gitignore22
-rw-r--r--libccnx-common/ccnx/common/test/CMakeLists.txt29
-rw-r--r--libccnx-common/ccnx/common/test/data.json2614
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_ContentObject.c634
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_Interest.c725
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_InterestPayloadId.c469
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_InterestReturn.c285
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_Key.c175
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_KeyLocator.c358
-rw-r--r--libccnx-common/ccnx/common/test/test_ccnx_KeystoreUtilities.c255
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_Link.c296
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_Manifest.c359
-rw-r--r--libccnx-common/ccnx/common/test/test_ccnx_ManifestHashGroup.c515
-rw-r--r--libccnx-common/ccnx/common/test/test_ccnx_Name.c735
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_NameLabel.c470
-rw-r--r--libccnx-common/ccnx/common/test/test_ccnx_NameSegment.c739
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_NameSegmentNumber.c241
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_TimeStamp.c217
-rwxr-xr-xlibccnx-common/ccnx/common/test/test_ccnx_WireFormatMessage.c502
19 files changed, 9640 insertions, 0 deletions
diff --git a/libccnx-common/ccnx/common/test/.gitignore b/libccnx-common/ccnx/common/test/.gitignore
new file mode 100644
index 00000000..dc9b70b3
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/.gitignore
@@ -0,0 +1,22 @@
+./Makefile.am
+./Makefile.in
+test_ccnx_BufferChunker
+test_ccnx_FileChunker
+test_ccnx_Chunker
+test_ccnx_ContentObject
+test_ccnx_Interest
+test_ccnx_Json
+test_ccnx_Key
+test_ccnx_KeyListEntry
+test_ccnx_KeyLocator
+test_ccnx_Link
+test_ccnx_Manifest
+test_ccnx_ManifestSection
+test_ccnx_Name
+test_ccnx_NameLabel
+test_ccnx_NameSegment
+test_ccnx_NameSegmentNumber
+test_ccnx_NameType
+test_ccnx_NetworkBuffer
+test_ccnx_TimeStamp
+test_ccnx_WireFormatMessage
diff --git a/libccnx-common/ccnx/common/test/CMakeLists.txt b/libccnx-common/ccnx/common/test/CMakeLists.txt
new file mode 100644
index 00000000..4cf70a14
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Enable gcov output for the tests
+add_definitions(--coverage)
+set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")
+
+configure_file(data.json data.json COPYONLY)
+
+set(TestsExpectedToPass
+ test_ccnx_ContentObject
+ test_ccnx_Interest
+ test_ccnx_InterestPayloadId
+ test_ccnx_InterestReturn
+ test_ccnx_KeyLocator
+ test_ccnx_KeystoreUtilities
+ test_ccnx_Link
+ test_ccnx_Manifest
+ test_ccnx_ManifestHashGroup
+ test_ccnx_Name
+ test_ccnx_NameLabel
+ test_ccnx_NameSegment
+ test_ccnx_NameSegmentNumber
+ test_ccnx_TimeStamp
+ test_ccnx_WireFormatMessage
+)
+
+
+foreach(test ${TestsExpectedToPass})
+ AddTest(${test})
+endforeach()
+
diff --git a/libccnx-common/ccnx/common/test/data.json b/libccnx-common/ccnx/common/test/data.json
new file mode 100644
index 00000000..a146f6ff
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/data.json
@@ -0,0 +1,2614 @@
+{
+ "array" : [
+ {
+ "id": 6104546,
+ "name": "-REPONAME",
+ "full_name": "mralexgray/-REPONAME",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/-REPONAME",
+ "description": null,
+ "fork": false,
+ "url": "https://api.github.com/repos/mralexgray/-REPONAME",
+ "forks_url": "https://api.github.com/repos/mralexgray/-REPONAME/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/-REPONAME/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/-REPONAME/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/-REPONAME/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/-REPONAME/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/-REPONAME/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/-REPONAME/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/-REPONAME/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/-REPONAME/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/-REPONAME/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/-REPONAME/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/-REPONAME/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/-REPONAME/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/-REPONAME/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/-REPONAME/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/-REPONAME/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/-REPONAME/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/-REPONAME/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/-REPONAME/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/-REPONAME/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/-REPONAME/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/-REPONAME/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/-REPONAME/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/-REPONAME/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/-REPONAME/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/-REPONAME/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/-REPONAME/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/-REPONAME/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/-REPONAME/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/-REPONAME/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/-REPONAME/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/-REPONAME/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/-REPONAME/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/-REPONAME/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/-REPONAME/releases{/id}",
+ "created_at": "2012-10-06T16:37:39Z",
+ "updated_at": "2013-01-12T13:39:30Z",
+ "pushed_at": "2012-10-06T16:37:39Z",
+ "git_url": "git://github.com/mralexgray/-REPONAME.git",
+ "ssh_url": "git@github.com:mralexgray/-REPONAME.git",
+ "clone_url": "https://github.com/mralexgray/-REPONAME.git",
+ "svn_url": "https://github.com/mralexgray/-REPONAME",
+ "homepage": null,
+ "size": 48,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": null,
+ "has_issues": true,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 13121042,
+ "name": "ace",
+ "full_name": "mralexgray/ace",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/ace",
+ "description": "Ace (Ajax.org Cloud9 Editor)",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/ace",
+ "forks_url": "https://api.github.com/repos/mralexgray/ace/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/ace/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/ace/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/ace/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/ace/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/ace/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/ace/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/ace/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/ace/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/ace/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/ace/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/ace/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/ace/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/ace/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/ace/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/ace/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/ace/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/ace/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/ace/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/ace/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/ace/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/ace/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/ace/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/ace/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/ace/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/ace/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/ace/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/ace/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/ace/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/ace/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/ace/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/ace/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/ace/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/ace/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/ace/releases{/id}",
+ "created_at": "2013-09-26T11:58:10Z",
+ "updated_at": "2013-10-26T12:34:49Z",
+ "pushed_at": "2013-10-26T12:34:48Z",
+ "git_url": "git://github.com/mralexgray/ace.git",
+ "ssh_url": "git@github.com:mralexgray/ace.git",
+ "clone_url": "https://github.com/mralexgray/ace.git",
+ "svn_url": "https://github.com/mralexgray/ace",
+ "homepage": "http://ace.c9.io",
+ "size": 21080,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "JavaScript",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 10791045,
+ "name": "ACEView",
+ "full_name": "mralexgray/ACEView",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/ACEView",
+ "description": "Use the wonderful ACE editor in your Cocoa applications",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/ACEView",
+ "forks_url": "https://api.github.com/repos/mralexgray/ACEView/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/ACEView/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/ACEView/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/ACEView/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/ACEView/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/ACEView/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/ACEView/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/ACEView/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/ACEView/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/ACEView/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/ACEView/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/ACEView/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/ACEView/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/ACEView/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/ACEView/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/ACEView/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/ACEView/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/ACEView/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/ACEView/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/ACEView/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/ACEView/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/ACEView/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/ACEView/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/ACEView/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/ACEView/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/ACEView/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/ACEView/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/ACEView/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/ACEView/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/ACEView/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/ACEView/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/ACEView/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/ACEView/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/ACEView/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/ACEView/releases{/id}",
+ "created_at": "2013-06-19T12:15:04Z",
+ "updated_at": "2013-10-30T12:39:24Z",
+ "pushed_at": "2013-10-30T12:39:18Z",
+ "git_url": "git://github.com/mralexgray/ACEView.git",
+ "ssh_url": "git@github.com:mralexgray/ACEView.git",
+ "clone_url": "https://github.com/mralexgray/ACEView.git",
+ "svn_url": "https://github.com/mralexgray/ACEView",
+ "homepage": null,
+ "size": 1661,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 13623648,
+ "name": "ActiveLog",
+ "full_name": "mralexgray/ActiveLog",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/ActiveLog",
+ "description": "Shut up all logs with active filter.",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/ActiveLog",
+ "forks_url": "https://api.github.com/repos/mralexgray/ActiveLog/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/ActiveLog/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/ActiveLog/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/ActiveLog/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/ActiveLog/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/ActiveLog/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/ActiveLog/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/ActiveLog/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/ActiveLog/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/ActiveLog/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/ActiveLog/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/ActiveLog/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/ActiveLog/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/ActiveLog/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/ActiveLog/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/ActiveLog/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/ActiveLog/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/ActiveLog/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/ActiveLog/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/ActiveLog/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/ActiveLog/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/ActiveLog/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/ActiveLog/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/ActiveLog/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/ActiveLog/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/ActiveLog/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/ActiveLog/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/ActiveLog/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/ActiveLog/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/ActiveLog/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/ActiveLog/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/ActiveLog/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/ActiveLog/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/ActiveLog/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/ActiveLog/releases{/id}",
+ "created_at": "2013-10-16T15:52:37Z",
+ "updated_at": "2013-10-16T15:52:37Z",
+ "pushed_at": "2011-07-03T06:28:59Z",
+ "git_url": "git://github.com/mralexgray/ActiveLog.git",
+ "ssh_url": "git@github.com:mralexgray/ActiveLog.git",
+ "clone_url": "https://github.com/mralexgray/ActiveLog.git",
+ "svn_url": "https://github.com/mralexgray/ActiveLog",
+ "homepage": "http://deepitpro.com/en/articles/ActiveLog/info/",
+ "size": 60,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 9716210,
+ "name": "adium",
+ "full_name": "mralexgray/adium",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/adium",
+ "description": "Official mirror of hg.adium.im",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/adium",
+ "forks_url": "https://api.github.com/repos/mralexgray/adium/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/adium/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/adium/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/adium/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/adium/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/adium/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/adium/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/adium/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/adium/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/adium/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/adium/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/adium/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/adium/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/adium/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/adium/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/adium/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/adium/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/adium/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/adium/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/adium/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/adium/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/adium/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/adium/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/adium/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/adium/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/adium/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/adium/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/adium/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/adium/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/adium/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/adium/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/adium/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/adium/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/adium/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/adium/releases{/id}",
+ "created_at": "2013-04-27T14:59:33Z",
+ "updated_at": "2013-04-27T14:59:33Z",
+ "pushed_at": "2013-04-26T16:43:53Z",
+ "git_url": "git://github.com/mralexgray/adium.git",
+ "ssh_url": "git@github.com:mralexgray/adium.git",
+ "clone_url": "https://github.com/mralexgray/adium.git",
+ "svn_url": "https://github.com/mralexgray/adium",
+ "homepage": null,
+ "size": 277719,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": false,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 12752329,
+ "name": "ADLivelyTableView",
+ "full_name": "mralexgray/ADLivelyTableView",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/ADLivelyTableView",
+ "description": "Lively UITableView",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/ADLivelyTableView",
+ "forks_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/ADLivelyTableView/releases{/id}",
+ "created_at": "2013-09-11T09:18:01Z",
+ "updated_at": "2013-09-11T09:18:03Z",
+ "pushed_at": "2012-05-10T10:40:15Z",
+ "git_url": "git://github.com/mralexgray/ADLivelyTableView.git",
+ "ssh_url": "git@github.com:mralexgray/ADLivelyTableView.git",
+ "clone_url": "https://github.com/mralexgray/ADLivelyTableView.git",
+ "svn_url": "https://github.com/mralexgray/ADLivelyTableView",
+ "homepage": "http://applidium.com/en/news/lively_uitableview/",
+ "size": 73,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 5697379,
+ "name": "AFIncrementalStore",
+ "full_name": "mralexgray/AFIncrementalStore",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AFIncrementalStore",
+ "description": "Core Data Persistence with AFNetworking, Done Right",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AFIncrementalStore",
+ "forks_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AFIncrementalStore/releases{/id}",
+ "created_at": "2012-09-06T04:20:33Z",
+ "updated_at": "2013-01-12T03:15:29Z",
+ "pushed_at": "2012-09-01T22:46:25Z",
+ "git_url": "git://github.com/mralexgray/AFIncrementalStore.git",
+ "ssh_url": "git@github.com:mralexgray/AFIncrementalStore.git",
+ "clone_url": "https://github.com/mralexgray/AFIncrementalStore.git",
+ "svn_url": "https://github.com/mralexgray/AFIncrementalStore",
+ "homepage": null,
+ "size": 139,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 6969621,
+ "name": "AFNetworking",
+ "full_name": "mralexgray/AFNetworking",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AFNetworking",
+ "description": "A delightful iOS and OS X networking framework",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AFNetworking",
+ "forks_url": "https://api.github.com/repos/mralexgray/AFNetworking/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AFNetworking/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AFNetworking/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AFNetworking/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AFNetworking/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AFNetworking/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AFNetworking/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AFNetworking/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AFNetworking/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AFNetworking/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AFNetworking/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AFNetworking/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AFNetworking/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AFNetworking/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AFNetworking/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AFNetworking/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AFNetworking/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AFNetworking/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AFNetworking/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AFNetworking/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AFNetworking/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AFNetworking/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AFNetworking/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AFNetworking/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AFNetworking/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AFNetworking/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AFNetworking/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AFNetworking/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AFNetworking/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AFNetworking/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AFNetworking/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AFNetworking/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AFNetworking/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AFNetworking/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AFNetworking/releases{/id}",
+ "created_at": "2012-12-02T17:00:04Z",
+ "updated_at": "2014-01-24T07:14:33Z",
+ "pushed_at": "2014-01-24T07:14:32Z",
+ "git_url": "git://github.com/mralexgray/AFNetworking.git",
+ "ssh_url": "git@github.com:mralexgray/AFNetworking.git",
+ "clone_url": "https://github.com/mralexgray/AFNetworking.git",
+ "svn_url": "https://github.com/mralexgray/AFNetworking",
+ "homepage": "http://afnetworking.com",
+ "size": 4341,
+ "stargazers_count": 1,
+ "watchers_count": 1,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 1,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 9485541,
+ "name": "AGNSSplitView",
+ "full_name": "mralexgray/AGNSSplitView",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AGNSSplitView",
+ "description": "Simple NSSplitView additions.",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AGNSSplitView",
+ "forks_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AGNSSplitView/releases{/id}",
+ "created_at": "2013-04-17T00:10:13Z",
+ "updated_at": "2013-04-17T00:10:13Z",
+ "pushed_at": "2013-02-26T00:32:32Z",
+ "git_url": "git://github.com/mralexgray/AGNSSplitView.git",
+ "ssh_url": "git@github.com:mralexgray/AGNSSplitView.git",
+ "clone_url": "https://github.com/mralexgray/AGNSSplitView.git",
+ "svn_url": "https://github.com/mralexgray/AGNSSplitView",
+ "homepage": null,
+ "size": 68,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 12767784,
+ "name": "AGScopeBar",
+ "full_name": "mralexgray/AGScopeBar",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AGScopeBar",
+ "description": "Custom scope bar implementation for Cocoa",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AGScopeBar",
+ "forks_url": "https://api.github.com/repos/mralexgray/AGScopeBar/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AGScopeBar/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AGScopeBar/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AGScopeBar/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AGScopeBar/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AGScopeBar/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AGScopeBar/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AGScopeBar/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AGScopeBar/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AGScopeBar/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AGScopeBar/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AGScopeBar/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AGScopeBar/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AGScopeBar/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AGScopeBar/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AGScopeBar/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AGScopeBar/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AGScopeBar/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AGScopeBar/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AGScopeBar/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AGScopeBar/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AGScopeBar/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AGScopeBar/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AGScopeBar/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AGScopeBar/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AGScopeBar/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AGScopeBar/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AGScopeBar/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AGScopeBar/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AGScopeBar/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AGScopeBar/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AGScopeBar/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AGScopeBar/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AGScopeBar/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AGScopeBar/releases{/id}",
+ "created_at": "2013-09-11T21:06:54Z",
+ "updated_at": "2013-09-11T21:06:54Z",
+ "pushed_at": "2013-05-07T03:35:29Z",
+ "git_url": "git://github.com/mralexgray/AGScopeBar.git",
+ "ssh_url": "git@github.com:mralexgray/AGScopeBar.git",
+ "clone_url": "https://github.com/mralexgray/AGScopeBar.git",
+ "svn_url": "https://github.com/mralexgray/AGScopeBar",
+ "homepage": null,
+ "size": 64,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 9227846,
+ "name": "AHContentBrowser",
+ "full_name": "mralexgray/AHContentBrowser",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AHContentBrowser",
+ "description": "A Mac only webview that loads a fast readable version of the website if available.",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AHContentBrowser",
+ "forks_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AHContentBrowser/releases{/id}",
+ "created_at": "2013-04-04T20:56:16Z",
+ "updated_at": "2013-04-04T20:56:16Z",
+ "pushed_at": "2013-03-13T17:38:23Z",
+ "git_url": "git://github.com/mralexgray/AHContentBrowser.git",
+ "ssh_url": "git@github.com:mralexgray/AHContentBrowser.git",
+ "clone_url": "https://github.com/mralexgray/AHContentBrowser.git",
+ "svn_url": "https://github.com/mralexgray/AHContentBrowser",
+ "homepage": "",
+ "size": 223,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 9167473,
+ "name": "AHLayout",
+ "full_name": "mralexgray/AHLayout",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AHLayout",
+ "description": "AHLayout",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AHLayout",
+ "forks_url": "https://api.github.com/repos/mralexgray/AHLayout/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AHLayout/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AHLayout/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AHLayout/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AHLayout/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AHLayout/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AHLayout/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AHLayout/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AHLayout/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AHLayout/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AHLayout/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AHLayout/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AHLayout/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AHLayout/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AHLayout/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AHLayout/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AHLayout/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AHLayout/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AHLayout/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AHLayout/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AHLayout/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AHLayout/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AHLayout/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AHLayout/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AHLayout/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AHLayout/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AHLayout/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AHLayout/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AHLayout/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AHLayout/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AHLayout/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AHLayout/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AHLayout/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AHLayout/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AHLayout/releases{/id}",
+ "created_at": "2013-04-02T10:10:30Z",
+ "updated_at": "2013-07-08T02:31:17Z",
+ "pushed_at": "2013-07-08T02:31:14Z",
+ "git_url": "git://github.com/mralexgray/AHLayout.git",
+ "ssh_url": "git@github.com:mralexgray/AHLayout.git",
+ "clone_url": "https://github.com/mralexgray/AHLayout.git",
+ "svn_url": "https://github.com/mralexgray/AHLayout",
+ "homepage": null,
+ "size": 359,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 18450201,
+ "name": "Airmail-Plug-In-Framework",
+ "full_name": "mralexgray/Airmail-Plug-In-Framework",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Airmail-Plug-In-Framework",
+ "description": "",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework",
+ "forks_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Airmail-Plug-In-Framework/releases{/id}",
+ "created_at": "2014-04-04T19:33:54Z",
+ "updated_at": "2014-04-04T19:33:54Z",
+ "pushed_at": "2014-03-27T15:42:19Z",
+ "git_url": "git://github.com/mralexgray/Airmail-Plug-In-Framework.git",
+ "ssh_url": "git@github.com:mralexgray/Airmail-Plug-In-Framework.git",
+ "clone_url": "https://github.com/mralexgray/Airmail-Plug-In-Framework.git",
+ "svn_url": "https://github.com/mralexgray/Airmail-Plug-In-Framework",
+ "homepage": null,
+ "size": 888,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": null,
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 5203219,
+ "name": "AJS-iTunes-API",
+ "full_name": "mralexgray/AJS-iTunes-API",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AJS-iTunes-API",
+ "description": "Cocoa wrapper for the iTunes search API - for iOS and Mac OSX projects",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API",
+ "forks_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AJS-iTunes-API/releases{/id}",
+ "created_at": "2012-07-27T10:20:58Z",
+ "updated_at": "2013-01-11T11:00:05Z",
+ "pushed_at": "2011-10-30T22:26:48Z",
+ "git_url": "git://github.com/mralexgray/AJS-iTunes-API.git",
+ "ssh_url": "git@github.com:mralexgray/AJS-iTunes-API.git",
+ "clone_url": "https://github.com/mralexgray/AJS-iTunes-API.git",
+ "svn_url": "https://github.com/mralexgray/AJS-iTunes-API",
+ "homepage": "",
+ "size": 103,
+ "stargazers_count": 1,
+ "watchers_count": 1,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 1,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 10093801,
+ "name": "Alcatraz",
+ "full_name": "mralexgray/Alcatraz",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Alcatraz",
+ "description": "The most awesome (and only) Xcode package manager!",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/Alcatraz",
+ "forks_url": "https://api.github.com/repos/mralexgray/Alcatraz/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Alcatraz/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Alcatraz/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Alcatraz/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Alcatraz/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Alcatraz/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Alcatraz/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Alcatraz/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Alcatraz/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Alcatraz/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Alcatraz/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Alcatraz/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Alcatraz/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Alcatraz/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Alcatraz/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Alcatraz/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Alcatraz/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Alcatraz/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Alcatraz/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Alcatraz/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Alcatraz/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Alcatraz/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Alcatraz/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Alcatraz/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Alcatraz/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Alcatraz/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Alcatraz/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Alcatraz/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Alcatraz/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Alcatraz/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Alcatraz/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Alcatraz/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Alcatraz/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Alcatraz/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Alcatraz/releases{/id}",
+ "created_at": "2013-05-16T04:41:13Z",
+ "updated_at": "2014-03-19T20:38:35Z",
+ "pushed_at": "2014-03-19T12:50:37Z",
+ "git_url": "git://github.com/mralexgray/Alcatraz.git",
+ "ssh_url": "git@github.com:mralexgray/Alcatraz.git",
+ "clone_url": "https://github.com/mralexgray/Alcatraz.git",
+ "svn_url": "https://github.com/mralexgray/Alcatraz",
+ "homepage": "mneorr.github.com/Alcatraz",
+ "size": 3668,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": false,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 12916552,
+ "name": "alcatraz-packages",
+ "full_name": "mralexgray/alcatraz-packages",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/alcatraz-packages",
+ "description": "Package list repository for Alcatraz",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/alcatraz-packages",
+ "forks_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/alcatraz-packages/releases{/id}",
+ "created_at": "2013-09-18T07:15:24Z",
+ "updated_at": "2013-09-18T07:15:25Z",
+ "pushed_at": "2013-09-09T07:51:48Z",
+ "git_url": "git://github.com/mralexgray/alcatraz-packages.git",
+ "ssh_url": "git@github.com:mralexgray/alcatraz-packages.git",
+ "clone_url": "https://github.com/mralexgray/alcatraz-packages.git",
+ "svn_url": "https://github.com/mralexgray/alcatraz-packages",
+ "homepage": "mneorr.github.com/Alcatraz",
+ "size": 482,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Ruby",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 10476467,
+ "name": "Alfred-Google-Translate",
+ "full_name": "mralexgray/Alfred-Google-Translate",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Alfred-Google-Translate",
+ "description": "Extension for Alfred that will do a Google translate for you",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate",
+ "forks_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Alfred-Google-Translate/releases{/id}",
+ "created_at": "2013-06-04T10:45:10Z",
+ "updated_at": "2013-06-04T10:45:10Z",
+ "pushed_at": "2013-01-12T19:39:03Z",
+ "git_url": "git://github.com/mralexgray/Alfred-Google-Translate.git",
+ "ssh_url": "git@github.com:mralexgray/Alfred-Google-Translate.git",
+ "clone_url": "https://github.com/mralexgray/Alfred-Google-Translate.git",
+ "svn_url": "https://github.com/mralexgray/Alfred-Google-Translate",
+ "homepage": null,
+ "size": 103,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Shell",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 5524019,
+ "name": "Amber",
+ "full_name": "mralexgray/Amber",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Amber",
+ "description": "Fork of the difficult-to-deal-with Amber.framework",
+ "fork": false,
+ "url": "https://api.github.com/repos/mralexgray/Amber",
+ "forks_url": "https://api.github.com/repos/mralexgray/Amber/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Amber/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Amber/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Amber/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Amber/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Amber/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Amber/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Amber/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Amber/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Amber/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Amber/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Amber/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Amber/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Amber/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Amber/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Amber/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Amber/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Amber/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Amber/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Amber/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Amber/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Amber/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Amber/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Amber/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Amber/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Amber/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Amber/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Amber/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Amber/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Amber/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Amber/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Amber/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Amber/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Amber/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Amber/releases{/id}",
+ "created_at": "2012-08-23T10:38:24Z",
+ "updated_at": "2013-01-11T22:25:35Z",
+ "pushed_at": "2012-08-23T10:38:25Z",
+ "git_url": "git://github.com/mralexgray/Amber.git",
+ "ssh_url": "git@github.com:mralexgray/Amber.git",
+ "clone_url": "https://github.com/mralexgray/Amber.git",
+ "svn_url": "https://github.com/mralexgray/Amber",
+ "homepage": null,
+ "size": 48,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": null,
+ "has_issues": true,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 10809060,
+ "name": "Amethyst",
+ "full_name": "mralexgray/Amethyst",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Amethyst",
+ "description": "Tiling window manager for OS X.",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/Amethyst",
+ "forks_url": "https://api.github.com/repos/mralexgray/Amethyst/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Amethyst/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Amethyst/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Amethyst/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Amethyst/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Amethyst/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Amethyst/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Amethyst/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Amethyst/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Amethyst/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Amethyst/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Amethyst/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Amethyst/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Amethyst/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Amethyst/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Amethyst/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Amethyst/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Amethyst/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Amethyst/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Amethyst/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Amethyst/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Amethyst/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Amethyst/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Amethyst/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Amethyst/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Amethyst/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Amethyst/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Amethyst/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Amethyst/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Amethyst/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Amethyst/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Amethyst/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Amethyst/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Amethyst/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Amethyst/releases{/id}",
+ "created_at": "2013-06-20T00:34:22Z",
+ "updated_at": "2013-06-20T00:34:22Z",
+ "pushed_at": "2013-06-18T02:54:11Z",
+ "git_url": "git://github.com/mralexgray/Amethyst.git",
+ "ssh_url": "git@github.com:mralexgray/Amethyst.git",
+ "clone_url": "https://github.com/mralexgray/Amethyst.git",
+ "svn_url": "https://github.com/mralexgray/Amethyst",
+ "homepage": "http://ianyh.github.io/Amethyst/",
+ "size": 12623,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 3684286,
+ "name": "Animated-Paths",
+ "full_name": "mralexgray/Animated-Paths",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Animated-Paths",
+ "description": "Demo project: Animating the drawing of a CGPath with CAShapeLayer.strokeEnd",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/Animated-Paths",
+ "forks_url": "https://api.github.com/repos/mralexgray/Animated-Paths/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Animated-Paths/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Animated-Paths/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Animated-Paths/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Animated-Paths/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Animated-Paths/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Animated-Paths/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Animated-Paths/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Animated-Paths/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Animated-Paths/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Animated-Paths/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Animated-Paths/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Animated-Paths/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Animated-Paths/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Animated-Paths/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Animated-Paths/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Animated-Paths/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Animated-Paths/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Animated-Paths/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Animated-Paths/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Animated-Paths/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Animated-Paths/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Animated-Paths/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Animated-Paths/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Animated-Paths/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Animated-Paths/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Animated-Paths/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Animated-Paths/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Animated-Paths/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Animated-Paths/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Animated-Paths/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Animated-Paths/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Animated-Paths/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Animated-Paths/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Animated-Paths/releases{/id}",
+ "created_at": "2012-03-11T02:56:38Z",
+ "updated_at": "2013-01-08T04:12:21Z",
+ "pushed_at": "2010-12-30T20:56:51Z",
+ "git_url": "git://github.com/mralexgray/Animated-Paths.git",
+ "ssh_url": "git@github.com:mralexgray/Animated-Paths.git",
+ "clone_url": "https://github.com/mralexgray/Animated-Paths.git",
+ "svn_url": "https://github.com/mralexgray/Animated-Paths",
+ "homepage": "http://oleb.net/blog/2010/12/animating-drawing-of-cgpath-with-cashapelayer/",
+ "size": 411,
+ "stargazers_count": 1,
+ "watchers_count": 1,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 1,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 16662874,
+ "name": "AnsiLove.framework",
+ "full_name": "mralexgray/AnsiLove.framework",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AnsiLove.framework",
+ "description": "Cocoa Framework for rendering ANSi / ASCII art",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AnsiLove.framework",
+ "forks_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AnsiLove.framework/releases{/id}",
+ "created_at": "2014-02-09T08:30:27Z",
+ "updated_at": "2014-02-09T08:30:32Z",
+ "pushed_at": "2013-10-04T14:08:38Z",
+ "git_url": "git://github.com/mralexgray/AnsiLove.framework.git",
+ "ssh_url": "git@github.com:mralexgray/AnsiLove.framework.git",
+ "clone_url": "https://github.com/mralexgray/AnsiLove.framework.git",
+ "svn_url": "https://github.com/mralexgray/AnsiLove.framework",
+ "homepage": "http://byteproject.net",
+ "size": 3780,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "M",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": false,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 5189563,
+ "name": "ANTrackBar",
+ "full_name": "mralexgray/ANTrackBar",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/ANTrackBar",
+ "description": "An easy-to-use Cocoa seek bar with a pleasing appearance",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/ANTrackBar",
+ "forks_url": "https://api.github.com/repos/mralexgray/ANTrackBar/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/ANTrackBar/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/ANTrackBar/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/ANTrackBar/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/ANTrackBar/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/ANTrackBar/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/ANTrackBar/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/ANTrackBar/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/ANTrackBar/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/ANTrackBar/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/ANTrackBar/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/ANTrackBar/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/ANTrackBar/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/ANTrackBar/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/ANTrackBar/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/ANTrackBar/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/ANTrackBar/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/ANTrackBar/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/ANTrackBar/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/ANTrackBar/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/ANTrackBar/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/ANTrackBar/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/ANTrackBar/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/ANTrackBar/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/ANTrackBar/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/ANTrackBar/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/ANTrackBar/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/ANTrackBar/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/ANTrackBar/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/ANTrackBar/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/ANTrackBar/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/ANTrackBar/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/ANTrackBar/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/ANTrackBar/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/ANTrackBar/releases{/id}",
+ "created_at": "2012-07-26T08:17:22Z",
+ "updated_at": "2013-01-11T10:29:56Z",
+ "pushed_at": "2012-03-09T01:40:02Z",
+ "git_url": "git://github.com/mralexgray/ANTrackBar.git",
+ "ssh_url": "git@github.com:mralexgray/ANTrackBar.git",
+ "clone_url": "https://github.com/mralexgray/ANTrackBar.git",
+ "svn_url": "https://github.com/mralexgray/ANTrackBar",
+ "homepage": "",
+ "size": 94,
+ "stargazers_count": 1,
+ "watchers_count": 1,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 1,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 16240152,
+ "name": "AOP-in-Objective-C",
+ "full_name": "mralexgray/AOP-in-Objective-C",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/AOP-in-Objective-C",
+ "description": "An NSProxy based library for easily enabling AOP like functionality in Objective-C.",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C",
+ "forks_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/AOP-in-Objective-C/releases{/id}",
+ "created_at": "2014-01-25T21:18:04Z",
+ "updated_at": "2014-02-12T16:23:21Z",
+ "pushed_at": "2014-02-12T16:23:20Z",
+ "git_url": "git://github.com/mralexgray/AOP-in-Objective-C.git",
+ "ssh_url": "git@github.com:mralexgray/AOP-in-Objective-C.git",
+ "clone_url": "https://github.com/mralexgray/AOP-in-Objective-C.git",
+ "svn_url": "https://github.com/mralexgray/AOP-in-Objective-C",
+ "homepage": "http://innoli.hu/en/opensource/",
+ "size": 340,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 1,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 1,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "travis-coveralls",
+ "master_branch": "travis-coveralls"
+ },
+ {
+ "id": 13141936,
+ "name": "Apaxy",
+ "full_name": "mralexgray/Apaxy",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Apaxy",
+ "description": "A simple, customisable theme for your Apache directory listing.",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/Apaxy",
+ "forks_url": "https://api.github.com/repos/mralexgray/Apaxy/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Apaxy/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Apaxy/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Apaxy/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Apaxy/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Apaxy/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Apaxy/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Apaxy/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Apaxy/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Apaxy/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Apaxy/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Apaxy/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Apaxy/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Apaxy/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Apaxy/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Apaxy/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Apaxy/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Apaxy/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Apaxy/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Apaxy/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Apaxy/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Apaxy/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Apaxy/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Apaxy/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Apaxy/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Apaxy/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Apaxy/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Apaxy/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Apaxy/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Apaxy/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Apaxy/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Apaxy/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Apaxy/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Apaxy/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Apaxy/releases{/id}",
+ "created_at": "2013-09-27T05:05:35Z",
+ "updated_at": "2013-09-27T05:05:36Z",
+ "pushed_at": "2013-08-02T16:01:32Z",
+ "git_url": "git://github.com/mralexgray/Apaxy.git",
+ "ssh_url": "git@github.com:mralexgray/Apaxy.git",
+ "clone_url": "https://github.com/mralexgray/Apaxy.git",
+ "svn_url": "https://github.com/mralexgray/Apaxy",
+ "homepage": null,
+ "size": 113,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "CSS",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 10048098,
+ "name": "appledoc",
+ "full_name": "mralexgray/appledoc",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/appledoc",
+ "description": "Objective-c code Apple style documentation set generator.",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/appledoc",
+ "forks_url": "https://api.github.com/repos/mralexgray/appledoc/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/appledoc/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/appledoc/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/appledoc/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/appledoc/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/appledoc/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/appledoc/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/appledoc/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/appledoc/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/appledoc/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/appledoc/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/appledoc/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/appledoc/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/appledoc/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/appledoc/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/appledoc/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/appledoc/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/appledoc/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/appledoc/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/appledoc/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/appledoc/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/appledoc/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/appledoc/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/appledoc/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/appledoc/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/appledoc/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/appledoc/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/appledoc/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/appledoc/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/appledoc/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/appledoc/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/appledoc/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/appledoc/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/appledoc/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/appledoc/releases{/id}",
+ "created_at": "2013-05-14T05:45:44Z",
+ "updated_at": "2014-02-09T08:14:42Z",
+ "pushed_at": "2014-02-09T08:14:42Z",
+ "git_url": "git://github.com/mralexgray/appledoc.git",
+ "ssh_url": "git@github.com:mralexgray/appledoc.git",
+ "clone_url": "https://github.com/mralexgray/appledoc.git",
+ "svn_url": "https://github.com/mralexgray/appledoc",
+ "homepage": "http://gentlebytes.com",
+ "size": 10336,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": false,
+ "has_wiki": false,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 16160992,
+ "name": "Appstore-Through-Terminal",
+ "full_name": "mralexgray/Appstore-Through-Terminal",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Appstore-Through-Terminal",
+ "description": "A simple debian package, made for iPhone, to open the iOS AppStore through terminal. Simple. Slightly usless. My work as a beginner.",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal",
+ "forks_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Appstore-Through-Terminal/releases{/id}",
+ "created_at": "2014-01-23T03:21:34Z",
+ "updated_at": "2014-01-23T03:21:34Z",
+ "pushed_at": "2011-12-21T06:40:25Z",
+ "git_url": "git://github.com/mralexgray/Appstore-Through-Terminal.git",
+ "ssh_url": "git@github.com:mralexgray/Appstore-Through-Terminal.git",
+ "clone_url": "https://github.com/mralexgray/Appstore-Through-Terminal.git",
+ "svn_url": "https://github.com/mralexgray/Appstore-Through-Terminal",
+ "homepage": "http://getagripon.com/tillie/projects.html",
+ "size": 104,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Shell",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 13709216,
+ "name": "appweb-4",
+ "full_name": "mralexgray/appweb-4",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/appweb-4",
+ "description": "Appweb Embeddable Web Server 4",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/appweb-4",
+ "forks_url": "https://api.github.com/repos/mralexgray/appweb-4/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/appweb-4/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/appweb-4/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/appweb-4/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/appweb-4/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/appweb-4/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/appweb-4/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/appweb-4/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/appweb-4/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/appweb-4/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/appweb-4/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/appweb-4/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/appweb-4/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/appweb-4/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/appweb-4/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/appweb-4/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/appweb-4/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/appweb-4/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/appweb-4/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/appweb-4/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/appweb-4/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/appweb-4/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/appweb-4/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/appweb-4/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/appweb-4/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/appweb-4/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/appweb-4/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/appweb-4/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/appweb-4/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/appweb-4/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/appweb-4/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/appweb-4/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/appweb-4/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/appweb-4/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/appweb-4/releases{/id}",
+ "created_at": "2013-10-19T21:36:10Z",
+ "updated_at": "2013-10-19T21:36:11Z",
+ "pushed_at": "2013-10-19T00:35:06Z",
+ "git_url": "git://github.com/mralexgray/appweb-4.git",
+ "ssh_url": "git@github.com:mralexgray/appweb-4.git",
+ "clone_url": "https://github.com/mralexgray/appweb-4.git",
+ "svn_url": "https://github.com/mralexgray/appweb-4",
+ "homepage": "http://appwebserver.org",
+ "size": 58244,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 12501983,
+ "name": "arbor",
+ "full_name": "mralexgray/arbor",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/arbor",
+ "description": "a graph visualization library using web workers and jQuery",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/arbor",
+ "forks_url": "https://api.github.com/repos/mralexgray/arbor/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/arbor/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/arbor/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/arbor/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/arbor/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/arbor/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/arbor/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/arbor/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/arbor/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/arbor/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/arbor/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/arbor/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/arbor/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/arbor/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/arbor/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/arbor/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/arbor/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/arbor/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/arbor/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/arbor/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/arbor/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/arbor/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/arbor/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/arbor/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/arbor/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/arbor/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/arbor/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/arbor/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/arbor/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/arbor/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/arbor/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/arbor/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/arbor/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/arbor/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/arbor/releases{/id}",
+ "created_at": "2013-08-31T07:07:05Z",
+ "updated_at": "2013-08-31T07:07:06Z",
+ "pushed_at": "2012-05-28T00:47:58Z",
+ "git_url": "git://github.com/mralexgray/arbor.git",
+ "ssh_url": "git@github.com:mralexgray/arbor.git",
+ "clone_url": "https://github.com/mralexgray/arbor.git",
+ "svn_url": "https://github.com/mralexgray/arbor",
+ "homepage": "http://arborjs.org",
+ "size": 237,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "JavaScript",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 13537888,
+ "name": "Archimedes",
+ "full_name": "mralexgray/Archimedes",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/Archimedes",
+ "description": "Geometry functions for Cocoa and Cocoa Touch",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/Archimedes",
+ "forks_url": "https://api.github.com/repos/mralexgray/Archimedes/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/Archimedes/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/Archimedes/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/Archimedes/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/Archimedes/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/Archimedes/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/Archimedes/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/Archimedes/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/Archimedes/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/Archimedes/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/Archimedes/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/Archimedes/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/Archimedes/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/Archimedes/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/Archimedes/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/Archimedes/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/Archimedes/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/Archimedes/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/Archimedes/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/Archimedes/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/Archimedes/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/Archimedes/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/Archimedes/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/Archimedes/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/Archimedes/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/Archimedes/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/Archimedes/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/Archimedes/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/Archimedes/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/Archimedes/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/Archimedes/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/Archimedes/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/Archimedes/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/Archimedes/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/Archimedes/releases{/id}",
+ "created_at": "2013-10-13T11:08:19Z",
+ "updated_at": "2014-04-06T00:41:21Z",
+ "pushed_at": "2014-04-06T00:41:20Z",
+ "git_url": "git://github.com/mralexgray/Archimedes.git",
+ "ssh_url": "git@github.com:mralexgray/Archimedes.git",
+ "clone_url": "https://github.com/mralexgray/Archimedes.git",
+ "svn_url": "https://github.com/mralexgray/Archimedes",
+ "homepage": null,
+ "size": 217,
+ "stargazers_count": 0,
+ "watchers_count": 0,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 0,
+ "default_branch": "master",
+ "master_branch": "master"
+ },
+ {
+ "id": 5260205,
+ "name": "arrsync",
+ "full_name": "mralexgray/arrsync",
+ "owner": {
+ "login": "mralexgray",
+ "id": 262517,
+ "avatar_url": "https://avatars.githubusercontent.com/u/262517?",
+ "gravatar_id": "50e7ed4eb2e7af000ea7d161748958f1",
+ "url": "https://api.github.com/users/mralexgray",
+ "html_url": "https://github.com/mralexgray",
+ "followers_url": "https://api.github.com/users/mralexgray/followers",
+ "following_url": "https://api.github.com/users/mralexgray/following{/other_user}",
+ "gists_url": "https://api.github.com/users/mralexgray/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/mralexgray/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/mralexgray/subscriptions",
+ "organizations_url": "https://api.github.com/users/mralexgray/orgs",
+ "repos_url": "https://api.github.com/users/mralexgray/repos",
+ "events_url": "https://api.github.com/users/mralexgray/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/mralexgray/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "private": false,
+ "html_url": "https://github.com/mralexgray/arrsync",
+ "description": "",
+ "fork": true,
+ "url": "https://api.github.com/repos/mralexgray/arrsync",
+ "forks_url": "https://api.github.com/repos/mralexgray/arrsync/forks",
+ "keys_url": "https://api.github.com/repos/mralexgray/arrsync/keys{/key_id}",
+ "collaborators_url": "https://api.github.com/repos/mralexgray/arrsync/collaborators{/collaborator}",
+ "teams_url": "https://api.github.com/repos/mralexgray/arrsync/teams",
+ "hooks_url": "https://api.github.com/repos/mralexgray/arrsync/hooks",
+ "issue_events_url": "https://api.github.com/repos/mralexgray/arrsync/issues/events{/number}",
+ "events_url": "https://api.github.com/repos/mralexgray/arrsync/events",
+ "assignees_url": "https://api.github.com/repos/mralexgray/arrsync/assignees{/user}",
+ "branches_url": "https://api.github.com/repos/mralexgray/arrsync/branches{/branch}",
+ "tags_url": "https://api.github.com/repos/mralexgray/arrsync/tags",
+ "blobs_url": "https://api.github.com/repos/mralexgray/arrsync/git/blobs{/sha}",
+ "git_tags_url": "https://api.github.com/repos/mralexgray/arrsync/git/tags{/sha}",
+ "git_refs_url": "https://api.github.com/repos/mralexgray/arrsync/git/refs{/sha}",
+ "trees_url": "https://api.github.com/repos/mralexgray/arrsync/git/trees{/sha}",
+ "statuses_url": "https://api.github.com/repos/mralexgray/arrsync/statuses/{sha}",
+ "languages_url": "https://api.github.com/repos/mralexgray/arrsync/languages",
+ "stargazers_url": "https://api.github.com/repos/mralexgray/arrsync/stargazers",
+ "contributors_url": "https://api.github.com/repos/mralexgray/arrsync/contributors",
+ "subscribers_url": "https://api.github.com/repos/mralexgray/arrsync/subscribers",
+ "subscription_url": "https://api.github.com/repos/mralexgray/arrsync/subscription",
+ "commits_url": "https://api.github.com/repos/mralexgray/arrsync/commits{/sha}",
+ "git_commits_url": "https://api.github.com/repos/mralexgray/arrsync/git/commits{/sha}",
+ "comments_url": "https://api.github.com/repos/mralexgray/arrsync/comments{/number}",
+ "issue_comment_url": "https://api.github.com/repos/mralexgray/arrsync/issues/comments/{number}",
+ "contents_url": "https://api.github.com/repos/mralexgray/arrsync/contents/{+path}",
+ "compare_url": "https://api.github.com/repos/mralexgray/arrsync/compare/{base}...{head}",
+ "merges_url": "https://api.github.com/repos/mralexgray/arrsync/merges",
+ "archive_url": "https://api.github.com/repos/mralexgray/arrsync/{archive_format}{/ref}",
+ "downloads_url": "https://api.github.com/repos/mralexgray/arrsync/downloads",
+ "issues_url": "https://api.github.com/repos/mralexgray/arrsync/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/mralexgray/arrsync/pulls{/number}",
+ "milestones_url": "https://api.github.com/repos/mralexgray/arrsync/milestones{/number}",
+ "notifications_url": "https://api.github.com/repos/mralexgray/arrsync/notifications{?since,all,participating}",
+ "labels_url": "https://api.github.com/repos/mralexgray/arrsync/labels{/name}",
+ "releases_url": "https://api.github.com/repos/mralexgray/arrsync/releases{/id}",
+ "created_at": "2012-08-01T14:21:49Z",
+ "updated_at": "2013-01-11T13:12:21Z",
+ "pushed_at": "2011-05-09T18:56:56Z",
+ "git_url": "git://github.com/mralexgray/arrsync.git",
+ "ssh_url": "git@github.com:mralexgray/arrsync.git",
+ "clone_url": "https://github.com/mralexgray/arrsync.git",
+ "svn_url": "https://github.com/mralexgray/arrsync",
+ "homepage": "",
+ "size": 194,
+ "stargazers_count": 2,
+ "watchers_count": 2,
+ "language": "Objective-C",
+ "has_issues": false,
+ "has_downloads": true,
+ "has_wiki": true,
+ "forks_count": 0,
+ "mirror_url": null,
+ "open_issues_count": 0,
+ "forks": 0,
+ "open_issues": 0,
+ "watchers": 2,
+ "default_branch": "master",
+ "master_branch": "master"
+ }
+]
+} \ No newline at end of file
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_ContentObject.c b/libccnx-common/ccnx/common/test/test_ccnx_ContentObject.c
new file mode 100755
index 00000000..20ed8c13
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_ContentObject.c
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../ccnx_ContentObject.c"
+
+#include <parc/algol/parc_SafeMemory.h>
+#include <LongBow/unit-test.h>
+
+#include <inttypes.h>
+#include <stdio.h>
+
+typedef struct test_data {
+ CCNxContentObjectInterface impl;
+ CCNxName *name;
+ CCNxContentObject *contentObject;
+ CCNxContentObject *namelessContentObject;
+} TestData;
+
+LONGBOW_TEST_RUNNER(ccnx_ContentObject)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(EmptyImpl);
+}
+
+static TestData *
+_commonSetup(void)
+{
+ TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
+
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/default/testData/content");
+ PARCBuffer *payload = parcBuffer_WrapCString("hello");
+
+ data->impl = CCNxContentObjectFacadeV1_Implementation;
+ data->name = name;
+ data->contentObject = ccnxContentObject_CreateWithImplAndPayload(&data->impl, name, CCNxPayloadType_DATA, payload);
+ data->namelessContentObject = ccnxContentObject_CreateWithImplAndPayload(&data->impl, NULL, CCNxPayloadType_DATA, payload);
+
+ parcBuffer_Release(&payload);
+ return data;
+}
+
+static void
+_commonTeardown(TestData *data)
+{
+ if (data->contentObject) {
+ ccnxContentObject_Release(&data->contentObject);
+ }
+ if (data->namelessContentObject) {
+ ccnxContentObject_Release(&data->namelessContentObject);
+ }
+ if (data->name) {
+ ccnxName_Release(&data->name);
+ }
+
+ parcMemory_Deallocate((void **) &data);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_ContentObject)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ContentObject)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_SetSignature);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_GetKeyId);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_CreateWithNameAndPayload);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_CreateWithPayload);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_HasFinalChunkNumber);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_GetSetFinalChunkNumber);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_GetName);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_GetNameWithNameless);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_GetPayload);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_GetPayloadType);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_AcquireRelease);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_HasExpiryTime);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_SetGetExpiryTime);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxContentObject_Display);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ longBowTestCase_SetClipBoardData(testCase, _commonSetup());
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ _commonTeardown(longBowTestCase_GetClipBoardData(testCase));
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_CreateWithNameAndPayload)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar");
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+ ccnxContentObject_AssertValid(contentObject);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&payload);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_CreateWithPayload)
+{
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithPayload(payload);
+ ccnxContentObject_AssertValid(contentObject);
+
+ parcBuffer_Release(&payload);
+ ccnxContentObject_Release(&contentObject);
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_Equals)
+{
+ CCNxName *nameA = ccnxName_CreateFromCString("ccnx:/foo/bar/A");
+ PARCBuffer *payloadA = parcBuffer_Allocate(100);
+
+ CCNxContentObject *objectA = ccnxContentObject_CreateWithNameAndPayload(nameA, payloadA);
+ ccnxContentObject_AssertValid(objectA);
+
+ assertTrue(ccnxContentObject_Equals(objectA, objectA), "Expected same instance to be equal");
+
+ CCNxContentObject *objectA2 = ccnxContentObject_CreateWithNameAndPayload(nameA, payloadA);
+ ccnxContentObject_AssertValid(objectA2);
+
+ assertTrue(ccnxContentObject_Equals(objectA, objectA2), "Expected ContentObject with same payload and name to be equal");
+
+ CCNxName *nameB = ccnxName_CreateFromCString("ccnx:/foo/bar/B");
+ CCNxContentObject *objectB = ccnxContentObject_CreateWithNameAndPayload(nameB, payloadA);
+ ccnxContentObject_AssertValid(objectB);
+
+ assertFalse(ccnxContentObject_Equals(objectA, objectB), "Expected ContentObject with same payload and different name");
+
+ ccnxName_Release(&nameA);
+ ccnxName_Release(&nameB);
+ parcBuffer_Release(&payloadA);
+
+ ccnxContentObject_Release(&objectA);
+ ccnxContentObject_Release(&objectA2);
+ ccnxContentObject_Release(&objectB);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_AcquireRelease)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar");
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+ ccnxContentObject_AssertValid(contentObject);
+
+ CCNxContentObject *reference = ccnxContentObject_Acquire(contentObject);
+ assertTrue(reference == contentObject, "Expected acquired reference to be equal to original");
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&payload);
+
+ ccnxContentObject_AssertValid(contentObject);
+ ccnxContentObject_AssertValid(reference);
+
+ ccnxContentObject_Release(&contentObject);
+
+ assertTrue(contentObject == NULL, "Expected contentObject pointer to be null");
+ ccnxContentObject_AssertValid(reference);
+
+ ccnxContentObject_Release(&reference);
+
+ assertTrue(reference == NULL, "Expected contentObject pointer to be null");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_HasFinalChunkNumber)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar");
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+ assertFalse(ccnxContentObject_HasFinalChunkNumber(contentObject), "Expected no final chunk number");
+
+ ccnxContentObject_SetFinalChunkNumber(contentObject, 100);
+ ccnxContentObject_AssertValid(contentObject);
+ assertTrue(ccnxContentObject_HasFinalChunkNumber(contentObject), "Expected HasFinalChunkNumber to return true");
+ assertTrue(ccnxContentObject_GetFinalChunkNumber(contentObject) == 100, "Expected final chunk number to be 100");
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&payload);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_GetSetFinalChunkNumber)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar");
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+
+ ccnxContentObject_SetFinalChunkNumber(contentObject, 100);
+ ccnxContentObject_AssertValid(contentObject);
+ assertTrue(ccnxContentObject_GetFinalChunkNumber(contentObject) == 100, "Expected final chunk number to be 100");
+
+ ccnxContentObject_SetFinalChunkNumber(contentObject, 20010);
+ ccnxContentObject_AssertValid(contentObject);
+ assertTrue(ccnxContentObject_GetFinalChunkNumber(contentObject) == 20010, "Expected final chunk number to be 20010");
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&payload);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_GetName)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar/baz");
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+ ccnxContentObject_AssertValid(contentObject);
+
+ CCNxName *actual = ccnxContentObject_GetName(contentObject);
+
+ assertTrue(actual == name, "Expected GetName() to return the original CCNxName");
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&payload);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_GetNameWithNameless)
+{
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithPayload(payload);
+ ccnxContentObject_AssertValid(contentObject);
+
+ CCNxName *actual = ccnxContentObject_GetName(contentObject);
+
+ assertNull(actual, "Nameless CCNxContentObjects have no name and must therefore be null.");
+
+ parcBuffer_Release(&payload);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_GetPayload)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/foo/bar");
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+ ccnxContentObject_AssertValid(contentObject);
+
+ PARCBuffer *actual = ccnxContentObject_GetPayload(contentObject);
+
+ assertTrue(actual == payload, "Expected GetPayload() to return the original PARCBuffer");
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&payload);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_GetPayloadType)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/name");
+ PARCBuffer *payload = parcBuffer_Allocate(100);
+
+ CCNxPayloadType types[] = {
+ CCNxPayloadType_DATA,
+ CCNxPayloadType_KEY,
+ CCNxPayloadType_LINK,
+ CCNxPayloadType_MANIFEST,
+ };
+
+
+ for (int i = 0; i < sizeof(types) / sizeof(CCNxPayloadType); i++) {
+ CCNxPayloadType type = types[i];
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, NULL);
+ ccnxContentObject_SetPayload(contentObject, type, payload);
+
+ assertTrue(ccnxContentObject_GetPayloadType(contentObject) == type, "Unexpected PayloadType");
+ ccnxContentObject_Release(&contentObject);
+ }
+
+ parcBuffer_Release(&payload);
+ ccnxName_Release(&name);
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_SetSignature)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/hello/dolly");
+ PARCBuffer *payload = parcBuffer_WrapCString("hello");
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+
+ PARCBuffer *keyId = parcBuffer_WrapCString("keyhash");
+ PARCBuffer *sigbits = parcBuffer_WrapCString("siggybits");
+ PARCSignature *signature = parcSignature_Create(PARCSigningAlgorithm_RSA, PARCCryptoHashType_SHA256, parcBuffer_Flip(sigbits));
+
+ ccnxContentObject_SetSignature(contentObject, keyId, signature, NULL);
+
+ parcBuffer_Release(&payload);
+ parcBuffer_Release(&sigbits);
+ parcBuffer_Release(&keyId);
+ parcSignature_Release(&signature);
+ ccnxName_Release(&name);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_GetKeyId)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/hello/dolly");
+ PARCBuffer *payload = parcBuffer_WrapCString("hello");
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+
+ assertNull(ccnxContentObject_GetKeyId(contentObject), "Expect NULL for KeyId here");
+
+ PARCBuffer *testKeyId = parcBuffer_WrapCString("keyhash");
+ PARCBuffer *sigbits = parcBuffer_WrapCString("siggybits");
+ PARCSignature *signature = parcSignature_Create(PARCSigningAlgorithm_RSA, PARCCryptoHashType_SHA256, parcBuffer_Flip(sigbits));
+
+ ccnxContentObject_SetSignature(contentObject, testKeyId, signature, NULL);
+
+ PARCBuffer *keyId = ccnxContentObject_GetKeyId(contentObject);
+
+ assertTrue(parcBuffer_Equals(keyId, testKeyId), "Expect key ids to match");
+
+ parcBuffer_Release(&payload);
+ parcBuffer_Release(&sigbits);
+ parcBuffer_Release(&keyId);
+ parcSignature_Release(&signature);
+ ccnxName_Release(&name);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_HasExpiryTime)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/hello/dolly");
+ PARCBuffer *payload = parcBuffer_WrapCString("hello");
+
+ // Use a V1 ContentObject, as V0 doesn't support ExpiryTime
+ CCNxContentObject *contentObject =
+ ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation,
+ name, CCNxPayloadType_DATA, payload);
+
+
+ assertFalse(ccnxContentObject_HasExpiryTime(contentObject), "Expected no expiration time by default");
+
+ parcBuffer_Release(&payload);
+ ccnxName_Release(&name);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_SetGetExpiryTime)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/hello/dolly");
+ PARCBuffer *payload = parcBuffer_WrapCString("hello");
+
+ // Use a V1 ContentObject, as V0 doesn't support ExpiryTime
+ CCNxContentObject *contentObject =
+ ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation,
+ name, CCNxPayloadType_DATA, payload);
+
+ assertFalse(ccnxContentObject_HasExpiryTime(contentObject), "Expected no expiration time by default");
+
+ uint64_t expiryTime = 1010101ULL;
+ ccnxContentObject_SetExpiryTime(contentObject, expiryTime);
+
+ assertTrue(ccnxContentObject_HasExpiryTime(contentObject), "Expected the expiryTime to be set");
+ uint64_t retrievedTime = ccnxContentObject_GetExpiryTime(contentObject);
+ assertTrue(expiryTime == retrievedTime, "Did not retrieve expected expiryTime from ContentObject");
+
+ parcBuffer_Release(&payload);
+ ccnxName_Release(&name);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(Global, ccnxContentObject_GetExpiryTimeWithNoExpiryTime, .event = &LongBowTrapUnexpectedStateEvent)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/hello/dolly");
+ PARCBuffer *payload = parcBuffer_WrapCString("hello");
+
+ // Use a V1 ContentObject, as V0 doesn't support ExpiryTime
+ CCNxContentObject *contentObject =
+ ccnxContentObject_CreateWithImplAndPayload(&CCNxContentObjectFacadeV1_Implementation,
+ name, CCNxPayloadType_DATA, payload);
+
+ // This should throw.
+ uint64_t retrievedTime = ccnxContentObject_GetExpiryTime(contentObject);
+ trapUnexpectedState("Expected to have thrown an exception when calling GetExpiryTime(), which returned %" PRIu64, retrievedTime);
+ parcBuffer_Release(&payload);
+ ccnxName_Release(&name);
+ ccnxContentObject_Release(&contentObject);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxContentObject_Display)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/hello/dolly");
+ PARCBuffer *payload = parcBuffer_WrapCString("hello");
+
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, payload);
+
+ ccnxContentObject_Display(contentObject, 0);
+
+ parcBuffer_Release(&payload);
+ ccnxName_Release(&name);
+ ccnxContentObject_Release(&contentObject);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Empty Implementation Tests
+///////////////////////////////////////////////////////////////////////////
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetPayloadType, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getPayloadType = NULL;
+
+ CCNxPayloadType type = ccnxContentObject_GetPayloadType(data->contentObject);
+ printf("We shouldn't get here. Payload = %d", type);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetPayload, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getPayload = NULL;
+
+ PARCBuffer *payload = ccnxContentObject_GetPayload(data->contentObject);
+ printf("We shouldn't get here. Payload = %p", (void *) payload);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetPayload, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.setPayload = NULL;
+
+ ccnxContentObject_SetPayload(data->contentObject, CCNxPayloadType_DATA, NULL);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetName, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getName = NULL;
+
+ CCNxName *name = ccnxContentObject_GetName(data->contentObject);
+ printf("We shouldn't get here. Name = %p", (void *) name);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetFinalChunkNumber, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.setFinalChunkNumber = NULL;
+
+ ccnxContentObject_SetFinalChunkNumber(data->contentObject, 100);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetFinalChunkNumber, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getFinalChunkNumber = NULL;
+
+ ccnxContentObject_SetFinalChunkNumber(data->contentObject, 100);
+ ccnxContentObject_GetFinalChunkNumber(data->contentObject);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetFinalChunkNumberNoHas, .event = &LongBowTrapUnexpectedStateEvent)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getFinalChunkNumber = NULL;
+
+ ccnxContentObject_GetFinalChunkNumber(data->contentObject);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_HasFinalChunkNumber, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.hasFinalChunkNumber = NULL;
+
+ if (ccnxContentObject_HasFinalChunkNumber(data->contentObject)) {
+ printf("Shouldn't get here");
+ }
+}
+
+LONGBOW_TEST_CASE(EmptyImpl, empty_HasExpiryTime)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.hasExpiryTime = NULL;
+
+ assertFalse(ccnxContentObject_HasExpiryTime(data->contentObject), "If no expiry time implementation, return false.");
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetExpiryTime, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.setExpiryTime = NULL;
+
+ ccnxContentObject_SetExpiryTime(data->contentObject, 100);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetExpiryTime, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getExpiryTime = NULL;
+
+ ccnxContentObject_SetExpiryTime(data->contentObject, 100);
+ uint64_t expiryTime = ccnxContentObject_GetExpiryTime(data->contentObject);
+ printf("We shouldn't get here, with expiryTime = %" PRIu64, expiryTime);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetExpiryTimeNoHas, .event = &LongBowTrapUnexpectedStateEvent)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getExpiryTime = NULL;
+
+ uint64_t expiryTime = ccnxContentObject_GetExpiryTime(data->contentObject);
+ printf("We shouldn't get here, with expiryTime = %" PRIu64, expiryTime);
+}
+
+LONGBOW_TEST_CASE(EmptyImpl, empty_Display)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.display = NULL;
+
+ ccnxContentObject_Display(data->contentObject, 2);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_ToString, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.toString = NULL;
+
+ const char *expectedString = ccnxContentObject_ToString(data->contentObject);
+ if (expectedString != NULL) {
+ parcMemory_Deallocate((void **) &expectedString);
+ }
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_Equals, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.equals = NULL;
+
+ if (ccnxContentObject_Equals(data->contentObject, data->contentObject)) {
+ printf("Shouldn't get here");
+ }
+}
+
+LONGBOW_TEST_FIXTURE(EmptyImpl)
+{
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_Display);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_HasExpiryTime);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetExpiryTime);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetExpiryTimeNoHas);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_SetExpiryTime);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_SetFinalChunkNumber);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetFinalChunkNumber);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetFinalChunkNumberNoHas);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_HasFinalChunkNumber);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetPayload);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetPayloadType);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_SetPayload);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetName);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_ToString);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_Equals);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(EmptyImpl)
+{
+ longBowTestCase_SetClipBoardData(testCase, _commonSetup());
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(EmptyImpl)
+{
+ _commonTeardown(longBowTestCase_GetClipBoardData(testCase));
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ContentObject);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_Interest.c b/libccnx-common/ccnx/common/test/test_ccnx_Interest.c
new file mode 100755
index 00000000..29debe9c
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_Interest.c
@@ -0,0 +1,725 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+#include <config.h>
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include <ccnx/common/ccnx_Interest.c>
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(ccnx_Interest)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(EmptyImpl);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_Interest)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_Interest)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_Create);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_CreateSimple);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_Release);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_AssertValid);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_Equals_Same);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_Equals);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_SetLifetime);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_GetLifetime);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_GetName);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_SetGetPayload);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_SetPayloadWithId);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_SetPayloadAndId);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_SetGetHopLimit);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_SetKeyIdRestriction);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_GetKeyIdRestriction);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_GetContentObjectHashRestriction);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_SetContentObjectHashRestriction);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_ToString);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterest_Display);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_Create)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *key = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(key, 1234L);
+
+ CCNxInterest *interest = ccnxInterest_Create(name,
+ 15 * 1000, /* lifetime, 15 seconds in milliseconds */
+ key, /* KeyId */
+ NULL /* ContentObjectHash */
+ );
+ ccnxName_Release(&name);
+ parcBuffer_Release(&key);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_CreateSimple)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_Release)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ CCNxInterest *reference = ccnxInterest_Acquire(interest);
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+ ccnxInterest_Release(&reference);
+
+ assertNull(interest, "Expected ccnxInterest_Release to null the pointer.");
+ assertNull(reference, "Expected ccnxInterest_Release to null the pointer.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_AssertValid)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/boose/roo/pie");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ ccnxInterest_AssertValid(interest);
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_Equals_Same)
+{
+ CCNxName *nameA = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *key = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(key, 1234L);
+
+ CCNxInterest *interestA = ccnxInterest_Create(nameA,
+ CCNxInterestDefault_LifetimeMilliseconds, /* lifetime */
+ key, /* KeyId */
+ NULL /* ContentObjectHash */
+ );
+
+ assertTrue(ccnxInterest_Equals(interestA, interestA), "Expected the same interest to be equal.");
+
+ assertFalse(ccnxInterest_Equals(interestA, NULL), "Did not expect NULL to equal an Interest");
+
+
+ ccnxName_Release(&nameA);
+ parcBuffer_Release(&key);
+ ccnxInterest_Release(&interestA);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_Equals)
+{
+ CCNxName *nameA = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *keyA = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(keyA, 1234L);
+
+ CCNxInterest *interestA = ccnxInterest_Create(nameA,
+ 1000, /* lifetime */
+ keyA, /* KeyId */
+ NULL /* ContentObjectHash */
+ );
+
+ CCNxName *nameB = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *keyB = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(keyB, 1234L);
+ CCNxInterest *interestB = ccnxInterest_Create(nameB,
+ 1000, /* lifetime */
+ keyB, /* KeyId */
+ NULL /* ContentObjectHash */
+ );
+
+ assertTrue(ccnxInterest_Equals(interestA, interestB), "Expected equivalent interests to be equal.");
+
+ ccnxName_Release(&nameA);
+ ccnxName_Release(&nameB);
+ parcBuffer_Release(&keyA);
+ parcBuffer_Release(&keyB);
+ ccnxInterest_Release(&interestA);
+ ccnxInterest_Release(&interestB);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_SetLifetime)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *key = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(key, 1234L);
+
+ uint32_t lifetime = 5000; // 5 seconds, in milliseconds
+
+ CCNxInterest *interest = ccnxInterest_Create(name,
+ lifetime, /* lifetime */
+ key, /* KeyId */
+ NULL /* ContentObjectHash */
+ );
+
+ uint32_t actual = ccnxInterest_GetLifetime(interest);
+
+ assertTrue(actual == lifetime, "Expected the retrieved lifetime to be equal to the assigned one.");
+
+ lifetime = 2000;
+ ccnxInterest_SetLifetime(interest, lifetime);
+ actual = ccnxInterest_GetLifetime(interest);
+
+ assertTrue(actual == lifetime, "Expected the retrieved lifetime to be equal to the assigned one.");
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&key);
+ ccnxInterest_Release(&interest);
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_GetLifetime)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *key = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(key, 1234L);
+
+ uint32_t lifetime = 5000; // 5 seconds, in milliseconds
+
+ CCNxInterest *interest = ccnxInterest_Create(name,
+ lifetime, /* lifetime */
+ key, /* KeyId */
+ NULL /* ContentObjectHash */
+ );
+
+ uint32_t actual = ccnxInterest_GetLifetime(interest);
+
+ assertTrue(actual == lifetime, "Expected the retrieved lifetime to be equal to the assigned one.");
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&key);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_GetName)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ CCNxName *actual = ccnxInterest_GetName(interest);
+ assertTrue(ccnxName_Equals(name, actual), "Expected the same name.");
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_SetKeyIdRestriction)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *key = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(key, 1234L);
+
+ CCNxInterest *interest = ccnxInterest_Create(name, 3000, NULL, NULL);
+ ccnxInterest_SetKeyIdRestriction(interest, key);
+ PARCBuffer *actual = ccnxInterest_GetKeyIdRestriction(interest);
+
+ actual = ccnxInterest_GetKeyIdRestriction(interest);
+ assertTrue(actual == key, "Expected retrieved key to be the same as assigned");
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+ parcBuffer_Release(&key);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_GetKeyIdRestriction)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *key = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(key, 1234L);
+
+ CCNxInterest *interest = ccnxInterest_Create(name, 3000, key, NULL);
+
+ PARCBuffer *actual = ccnxInterest_GetKeyIdRestriction(interest);
+
+ actual = ccnxInterest_GetKeyIdRestriction(interest);
+ assertTrue(actual == key, "Expected retrieved key to be the same as assigned");
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+ parcBuffer_Release(&key);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_SetContentObjectHashRestriction)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *coh = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(coh, 77573L);
+
+ CCNxInterest *interest = ccnxInterest_Create(name, CCNxInterestDefault_LifetimeMilliseconds, NULL, NULL);
+
+ PARCBuffer *actual = ccnxInterest_GetContentObjectHashRestriction(interest);
+ assertNull(actual, "Expected retrieved ContentObjectHash to be initially NULL");
+
+ ccnxInterest_SetContentObjectHashRestriction(interest, coh);
+ actual = ccnxInterest_GetContentObjectHashRestriction(interest);
+
+ assertTrue(actual == coh, "Expected retrieved ContentObjectHash to be the same as assigned");
+
+ // Re-setting is not yet supported. At the moment, you can only put the COHR once.
+ // Now change it, and validate.
+ //PARCBuffer *coh2 = parcBuffer_Allocate(8);
+ //parcBuffer_PutUint64(coh2, 3262L);
+ //ccnxInterest_SetContentObjectHashRestriction(interest, coh2);
+ //actual = ccnxInterest_GetContentObjectHashRestriction(interest);
+ //assertTrue(actual == coh2, "Expected retrieved ContentObjectHash to be the same as assigned");
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+ parcBuffer_Release(&coh);
+ //parcBuffer_Release(&coh2);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_GetContentObjectHashRestriction)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ PARCBuffer *coh = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(coh, 1234L);
+
+ CCNxInterest *interest = ccnxInterest_Create(name, CCNxInterestDefault_LifetimeMilliseconds, NULL, coh);
+
+ PARCBuffer *actual = ccnxInterest_GetContentObjectHashRestriction(interest);
+
+ assertTrue(actual == coh, "Expected retrieved ContentObjectHash to be the same as assigned");
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+ parcBuffer_Release(&coh);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_SetGetPayload)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ CCNxName *origNameCopy = ccnxName_Copy(name);
+
+ CCNxInterestInterface *impl = ccnxInterestInterface_GetInterface(interest);
+
+ if (impl->getPayload) {
+ assertNull(ccnxInterest_GetPayload(interest), "Expected a NULL payload");
+ }
+
+ if (impl->getPayload && impl->setPayload) {
+ PARCBuffer *payload = parcBuffer_WrapCString("impls have pimples");
+ ccnxInterest_SetPayload(interest, payload);
+
+ PARCBuffer *payloadOut = ccnxInterest_GetPayload(interest);
+
+ assertTrue(parcBuffer_Equals(payload, payloadOut), "Expected an equal buffer");
+
+ CCNxName *nameAfterPayload = ccnxInterest_GetName(interest);
+ assertTrue(ccnxName_Equals(nameAfterPayload, origNameCopy), "Expected an unmodified name");
+
+ parcBuffer_Release(&payload);
+ }
+ ccnxName_Release(&name);
+ ccnxName_Release(&origNameCopy);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_SetPayloadAndId)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ CCNxInterestInterface *impl = ccnxInterestInterface_GetInterface(interest);
+
+ if (impl->getPayload) {
+ assertNull(ccnxInterest_GetPayload(interest), "Expected a NULL payload");
+ }
+
+ if (impl->getPayload && impl->setPayload) {
+ PARCBuffer *payload = parcBuffer_WrapCString("impls have pimples");
+
+ ccnxInterest_SetPayloadAndId(interest, payload);
+
+ PARCBuffer *payloadOut = ccnxInterest_GetPayload(interest);
+
+ assertTrue(parcBuffer_Equals(payload, payloadOut), "Expected an equal buffer");
+
+ CCNxName *nameAfterPayload = ccnxInterest_GetName(interest);
+ CCNxNameSegment *segment = ccnxName_GetSegment(nameAfterPayload, ccnxName_GetSegmentCount(nameAfterPayload) - 1);
+
+ assertTrue(ccnxNameSegment_GetType(segment) == CCNxNameLabelType_PAYLOADID, "Expected to find a payload ID appended to the name");
+
+ parcBuffer_Release(&payload);
+ }
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_SetPayloadWithId)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+ CCNxName *origNameCopy = ccnxName_Copy(name);
+
+ CCNxInterestInterface *impl = ccnxInterestInterface_GetInterface(interest);
+
+ if (impl->getPayload) {
+ assertNull(ccnxInterest_GetPayload(interest), "Expected a NULL payload");
+ }
+
+ if (impl->getPayload && impl->setPayload) {
+ PARCBuffer *payload = parcBuffer_WrapCString("impls have pimples");
+ PARCBuffer *payloadIdBuffer = parcBuffer_WrapCString("payload Id buffer");
+
+ CCNxInterestPayloadId *payloadId = ccnxInterestPayloadId_Create(payloadIdBuffer,
+ CCNxInterestPayloadId_TypeCode_App + 2);
+
+ ccnxInterest_SetPayloadWithId(interest, payload, payloadId);
+
+ PARCBuffer *payloadOut = ccnxInterest_GetPayload(interest);
+
+ assertTrue(parcBuffer_Equals(payload, payloadOut), "Expected an equal buffer");
+
+ CCNxName *nameAfterPayload = ccnxInterest_GetName(interest);
+ CCNxNameSegment *segment = ccnxName_GetSegment(nameAfterPayload, ccnxName_GetSegmentCount(nameAfterPayload) - 1);
+
+ assertTrue(ccnxNameSegment_GetType(segment) == CCNxNameLabelType_PAYLOADID, "Expected to find a payload ID appended to the name");
+
+ CCNxInterestPayloadId *outId = ccnxInterestPayloadId_CreateFromSegmentInName(nameAfterPayload);
+ assertTrue(ccnxInterestPayloadId_Equals(outId, payloadId), "expected to see the same payload Id after setting the payload");
+
+ ccnxInterestPayloadId_Release(&payloadId);
+ ccnxInterestPayloadId_Release(&outId);
+
+ parcBuffer_Release(&payload);
+ parcBuffer_Release(&payloadIdBuffer);
+ }
+ ccnxName_Release(&name);
+ ccnxName_Release(&origNameCopy);
+ ccnxInterest_Release(&interest);
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_SetGetHopLimit)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_CreateSimple(name);
+
+ CCNxInterestInterface *impl = ccnxInterestInterface_GetInterface(interest);
+
+ if (impl->getHopLimit) {
+ assertTrue(ccnxInterest_GetHopLimit(interest) == CCNxInterestDefault_HopLimit, "Expected the default hop limit");
+ }
+
+ if (impl->setHopLimit && impl->getHopLimit) {
+ ccnxInterest_SetHopLimit(interest, 10);
+ assertTrue(ccnxInterest_GetHopLimit(interest) == 10, "Expected a hopLimit of 10");
+ ccnxInterest_SetHopLimit(interest, 20);
+ assertTrue(ccnxInterest_GetHopLimit(interest) == 20, "Expected a hopLimit of 20");
+ }
+
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_ToString)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_Create(name,
+ CCNxInterestDefault_LifetimeMilliseconds, /* lifetime */
+ NULL, /* KeyId */
+ NULL /* ContentObjectHash */
+ );
+
+ const char *expectedString = ccnxInterest_ToString(interest);
+ assertNotNull(expectedString, "Expected non-null result from ccnxInterest_ToString.");
+
+ parcMemory_Deallocate((void **) &expectedString);
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterest_Display)
+{
+ PARCBuffer *coh = parcBuffer_Allocate(8);
+ parcBuffer_PutUint64(coh, 7778L);
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/name");
+ CCNxInterest *interest = ccnxInterest_Create(name,
+ 100, /* lifetime */
+ NULL, /* KeyId */
+ coh); /* ContentObjectHash */
+
+ ccnxInterest_Display(interest, 2);
+ ccnxName_Release(&name);
+ ccnxInterest_Release(&interest);
+ parcBuffer_Release(&coh);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Empty Implementation tests
+///////////////////////////////////////////////////////////////////////////////
+
+
+typedef struct test_data {
+ CCNxInterestInterface impl;
+ CCNxName *name;
+ CCNxInterest *interest;
+} TestData;
+
+
+static TestData *
+_commonSetup(void)
+{
+ TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/default/testData/content");
+
+ data->impl = CCNxInterestFacadeV1_Implementation; // This copies the struct each time.
+ data->name = name;
+ data->interest = ccnxInterest_CreateWithImpl(&data->impl, name, 100, NULL, NULL, 10);
+
+ return data;
+}
+
+static void
+_commonTeardown(TestData *data)
+{
+ if (data->interest) {
+ ccnxInterest_Release(&data->interest);
+ }
+ if (data->name) {
+ ccnxName_Release(&data->name);
+ }
+
+ parcMemory_Deallocate((void **) &data);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(EmptyImpl)
+{
+ longBowTestCase_SetClipBoardData(testCase, _commonSetup());
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(EmptyImpl)
+{
+ _commonTeardown(longBowTestCase_GetClipBoardData(testCase));
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+
+LONGBOW_TEST_CASE(EmptyImpl, empty_Display)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.display = NULL;
+
+ ccnxInterest_Display(data->interest, 2);
+}
+
+LONGBOW_TEST_CASE(EmptyImpl, empty_ToString)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.toString = NULL;
+
+ const char *expectedString = ccnxInterest_ToString(data->interest);
+ if (expectedString != NULL) {
+ parcMemory_Deallocate((void **) &expectedString);
+ }
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetName, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getName = NULL;
+
+ CCNxName *name = ccnxInterest_GetName(data->interest);
+ printf("Shouldn't get here. name = %p\n", (void *) name);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetHopLimit, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.setHopLimit = NULL;
+
+ if (ccnxInterest_SetHopLimit(data->interest, 10)) {
+ printf("Shouldn't get here");
+ }
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetHopLimit, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getHopLimit = NULL;
+
+ uint32_t hopLimit = ccnxInterest_GetHopLimit(data->interest);
+ printf("Shouldn't get here. hopLimit = %u\n", hopLimit);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetLifetime, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.setLifetime = NULL;
+
+ if (ccnxInterest_SetLifetime(data->interest, 10)) {
+ printf("Shouldn't get here");
+ }
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetLifetime, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getLifetime = NULL;
+
+ uint32_t lifetime = ccnxInterest_GetLifetime(data->interest);
+ printf("Shouldn't get here. lifetime = %u\n", lifetime);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetKeyIdRestriction, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.setKeyIdRestriction = NULL;
+
+ if (ccnxInterest_SetKeyIdRestriction(data->interest, NULL)) {
+ printf("Shouldn't get here");
+ }
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetKeyIdRestriction, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getKeyIdRestriction = NULL;
+
+ PARCBuffer *keyIdRestriction = ccnxInterest_GetKeyIdRestriction(data->interest);
+ printf("Shouldn't get here. getKeyIdRestriction = %p\n", (void *) keyIdRestriction);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetContentObjectHashRestriction, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.setContentObjectHashRestriction = NULL;
+
+ if (ccnxInterest_SetContentObjectHashRestriction(data->interest, NULL)) {
+ printf("Shouldn't get here");
+ }
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetContentObjectHashRestriction, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getContentObjectHashRestriction = NULL;
+
+ PARCBuffer *restriction = ccnxInterest_GetContentObjectHashRestriction(data->interest);
+ printf("Shouldn't get here. restriction = %p\n", (void *) restriction);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_SetPayload, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.setPayload = NULL;
+
+ if (ccnxInterest_SetPayload(data->interest, NULL)) {
+ printf("Shouldn't get here");
+ }
+}
+
+LONGBOW_TEST_CASE_EXPECTS(EmptyImpl, empty_GetPayload, .event = &LongBowTrapNotImplemented)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ data->impl.getPayload = NULL;
+
+ PARCBuffer *payload = ccnxInterest_GetPayload(data->interest);
+ printf("Shouldn't get here. payload = %p\n", (void *) payload);
+}
+
+LONGBOW_TEST_FIXTURE(EmptyImpl)
+{
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_Display);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_ToString);
+
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetName);
+
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetHopLimit);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_SetHopLimit);
+
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetLifetime);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_SetLifetime);
+
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetKeyIdRestriction);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_SetKeyIdRestriction);
+
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetContentObjectHashRestriction);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_SetContentObjectHashRestriction);
+
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_GetPayload);
+ LONGBOW_RUN_TEST_CASE(EmptyImpl, empty_SetPayload);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_Interest);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_InterestPayloadId.c b/libccnx-common/ccnx/common/test/test_ccnx_InterestPayloadId.c
new file mode 100755
index 00000000..28e07643
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_InterestPayloadId.c
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include <config.h>
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <stdio.h>
+
+#include "../ccnx_InterestPayloadId.c"
+
+static const PARCMemoryInterface *_originalMemoryProvider;
+
+LONGBOW_TEST_RUNNER(ccnx_InterestPayloadId)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Error);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_InterestPayloadId)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_InterestPayloadId)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_CreateWithAppDefinedType);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_CreateAsCryptoHash);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_CreateFromSegmentInName);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_CreateFromSegmentInName_NotFound);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_Acquire);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_GetNameSegment);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_GetValue);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_GetType);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_IsValid);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_ToString);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_Copy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_NotEquals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_Compare);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestPayloadId_HashCode);
+}
+
+typedef struct {
+ uint8_t type;
+ PARCBuffer *value;
+} TestData;
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ _originalMemoryProvider = parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
+ assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData));
+ data->value = parcBuffer_WrapCString("123456789abcdef");
+ data->type = 42 + CCNxInterestPayloadId_TypeCode_App;
+ longBowTestCase_SetClipBoardData(testCase, data);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ parcBuffer_Release(&data->value);
+ parcMemory_Deallocate((void **) &data);
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestRunner_GetName(testRunner), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ parcMemory_SetInterface(_originalMemoryProvider);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_CreateWithAppDefinedType)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ assertNotNull(ipId, "Expect a non-NULL result from Create");
+ ccnxInterestPayloadId_AssertValid(ipId);
+
+ parcBuffer_Release(&value);
+
+ assertTrue(ccnxInterestPayloadId_IsValid(ipId), "Expected a valid CCNxInteresPayloadId.");
+ ccnxInterestPayloadId_Release(&ipId);
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_CreateAsCryptoHash)
+{
+ PARCBuffer *value = parcBuffer_WrapCString("123456789abcdef");
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_CreateAsSHA256Hash(value);
+ assertNotNull(ipId, "Expect a non-NULL result from CreateByHash");
+ ccnxInterestPayloadId_AssertValid(ipId);
+
+ parcBuffer_Release(&value);
+
+ assertTrue(ccnxInterestPayloadId_IsValid(ipId), "Expected a valid CCNxInteresPayloadId.");
+ ccnxInterestPayloadId_Release(&ipId);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_CreateFromSegmentInName)
+{
+ PARCBuffer *value = parcBuffer_WrapCString("123456789abcdef");
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_CreateAsSHA256Hash(value);
+ parcBuffer_Release(&value);
+ assertNotNull(ipId, "Expect a non-NULL result from CreateByHash");
+ ccnxInterestPayloadId_AssertValid(ipId);
+ assertTrue(ccnxInterestPayloadId_IsValid(ipId), "Expected a valid CCNxInteresPayloadId.");
+
+ CCNxName *name = ccnxName_CreateFromCString("lci:/segment1/segment2/segment3");
+ ccnxName_Append(name, ccnxInterestPayloadId_GetNameSegment(ipId));
+
+ CCNxInterestPayloadId *result = ccnxInterestPayloadId_CreateFromSegmentInName(name);
+ ccnxName_Release(&name);
+
+ assertNotNull(result, "Should have found a payload ID");
+ ccnxInterestPayloadId_AssertValid(result);
+
+ assertTrue(ccnxInterestPayloadId_Equals(result, ipId),
+ "Expected source and result Interest Payload IDs to be equal");
+
+ ccnxInterestPayloadId_Release(&ipId);
+ ccnxInterestPayloadId_Release(&result);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_CreateFromSegmentInName_NotFound)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/segment1/segment2/segment3");
+ CCNxInterestPayloadId *result = ccnxInterestPayloadId_CreateFromSegmentInName(name);
+ ccnxName_Release(&name);
+
+ assertNull(result, "Should have not found a payload ID");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_Acquire)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ parcBuffer_Release(&value);
+ ccnxInterestPayloadId_AssertValid(ipId);
+
+ CCNxInterestPayloadId *ipIdAcq = ccnxInterestPayloadId_Acquire(ipId);
+ ccnxInterestPayloadId_AssertValid(ipIdAcq);
+
+ ccnxInterestPayloadId_Release(&ipId);
+ ccnxInterestPayloadId_Release(&ipIdAcq);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_GetValue)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ ccnxInterestPayloadId_AssertValid(ipId);
+
+ assertTrue(parcBuffer_Equals(ccnxInterestPayloadId_GetValue(ipId), value),
+ "Expect GetId to produce the correct result");
+
+ parcBuffer_Release(&value);
+ ccnxInterestPayloadId_Release(&ipId);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_GetType)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ ccnxInterestPayloadId_AssertValid(ipId);
+
+ assertTrue(ccnxInterestPayloadId_GetType(ipId) == type,
+ "Expect GetId to produce the correct result");
+
+ parcBuffer_Release(&value);
+ ccnxInterestPayloadId_Release(&ipId);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_GetType_App)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ ccnxInterestPayloadId_AssertValid(ipId);
+
+ assertTrue(parcBuffer_Equals(ccnxInterestPayloadId_GetValue(ipId), value),
+ "Expect GetId to produce the correct result");
+
+ parcBuffer_Release(&value);
+ ccnxInterestPayloadId_Release(&ipId);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_HashCode)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId1 = ccnxInterestPayloadId_Create(value, type);
+ uint32_t hashCode1 = ccnxInterestPayloadId_HashCode(ipId1);
+ CCNxInterestPayloadId *ipId2 = ccnxInterestPayloadId_Create(value, type);
+ uint32_t hashCode2 = ccnxInterestPayloadId_HashCode(ipId2);
+ assertTrue(hashCode1 == hashCode2, "Expect hash codes of equal objects to be equal");
+ parcBuffer_Release(&value);
+ ccnxInterestPayloadId_Release(&ipId1);
+ ccnxInterestPayloadId_Release(&ipId2);
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_Equals)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_WrapCString("123456789abcdef");
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ ccnxInterestPayloadId_AssertValid(ipId);
+
+ PARCBuffer *value2 = parcBuffer_WrapCString("123456789abcdef");
+ CCNxInterestPayloadId *ipId2 = ccnxInterestPayloadId_Create(value2, type);
+ ccnxInterestPayloadId_AssertValid(ipId2);
+
+ assertTrue(ccnxInterestPayloadId_Equals(ipId, ipId2),
+ "Expect InterestPayloadIds to be equal");
+
+ CCNxInterestPayloadId *ipId3 = ccnxInterestPayloadId_Create(value, type);
+ ccnxInterestPayloadId_AssertValid(ipId3);
+
+ assertTrue(ccnxInterestPayloadId_Equals(ipId, ipId3),
+ "Expect InterestPayloadIds to be equal");
+
+ parcBuffer_Release(&value);
+ parcBuffer_Release(&value2);
+ ccnxInterestPayloadId_Release(&ipId);
+ ccnxInterestPayloadId_Release(&ipId2);
+ ccnxInterestPayloadId_Release(&ipId3);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_NotEquals)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_WrapCString("123456789abcdef");
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ ccnxInterestPayloadId_AssertValid(ipId);
+
+ PARCBuffer *value2 = parcBuffer_WrapCString("123456789abcdex");
+ CCNxInterestPayloadId *ipId2 = ccnxInterestPayloadId_Create(value2, type);
+ ccnxInterestPayloadId_AssertValid(ipId2);
+
+ assertTrue(!ccnxInterestPayloadId_Equals(ipId, ipId2),
+ "Expect InterestPayloadIds to be equal");
+
+ parcBuffer_Release(&value);
+ parcBuffer_Release(&value2);
+ ccnxInterestPayloadId_Release(&ipId);
+ ccnxInterestPayloadId_Release(&ipId2);
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_Compare)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value1 = parcBuffer_WrapCString("123456789abcdef");
+ CCNxInterestPayloadId *ipId1 = ccnxInterestPayloadId_Create(value1, type);
+ ccnxInterestPayloadId_AssertValid(ipId1);
+
+ assertTrue(ccnxInterestPayloadId_Compare(ipId1, ipId1) == 0,
+ "Expect compare result of 0 when comparing InterestPayloadId to itself");
+
+ PARCBuffer *value1p = parcBuffer_WrapCString("123456789abcdef");
+ CCNxInterestPayloadId *ipId1p = ccnxInterestPayloadId_Create(value1p, type);
+ ccnxInterestPayloadId_AssertValid(ipId1p);
+
+ assertTrue(ccnxInterestPayloadId_Compare(ipId1, ipId1p) == 0,
+ "Expect compare result of 0 when comparing InterestPayloadIds with the same content");
+
+ PARCBuffer *value2 = parcBuffer_WrapCString("123456789abcdex");
+ CCNxInterestPayloadId *ipId2 = ccnxInterestPayloadId_Create(value2, type);
+ ccnxInterestPayloadId_AssertValid(ipId2);
+
+ assertTrue(ccnxInterestPayloadId_Compare(ipId2, ipId1) > 0,
+ "Expect compare result > 0 when comparing InterestPayloadId2 to InterestPayloadId1");
+
+ parcBuffer_Release(&value1);
+ parcBuffer_Release(&value1p);
+ parcBuffer_Release(&value2);
+
+ ccnxInterestPayloadId_Release(&ipId1);
+ ccnxInterestPayloadId_Release(&ipId1p);
+ ccnxInterestPayloadId_Release(&ipId2);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_Copy)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value1 = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId1 = ccnxInterestPayloadId_Create(value1, type);
+ parcBuffer_Release(&value1);
+ ccnxInterestPayloadId_AssertValid(ipId1);
+
+ CCNxInterestPayloadId *ipIdCopy = ccnxInterestPayloadId_Copy(ipId1);
+ ccnxInterestPayloadId_AssertValid(ipIdCopy);
+ assertTrue(ccnxInterestPayloadId_Equals(ipId1, ipIdCopy), "Expect original and copy InterestPayloadId to be equal");
+
+ ccnxInterestPayloadId_Release(&ipId1);
+ ccnxInterestPayloadId_Release(&ipIdCopy);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_IsValid)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ parcBuffer_Release(&value);
+
+ assertTrue(ccnxInterestPayloadId_IsValid(ipId), "Expected a valid CCNxInteresPayloadId.");
+ ccnxInterestPayloadId_Release(&ipId);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_ToString)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ char *test = "123456789abcdef";
+ PARCBuffer *value = parcBuffer_WrapCString(test);
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+ parcBuffer_Release(&value);
+
+ char *result = ccnxInterestPayloadId_ToString(ipId);
+ assertNotNull(result, "Expect a non-NULL result from ToString");
+ ccnxInterestPayloadId_Release(&ipId);
+
+ PARCBufferComposer *composer = parcBufferComposer_Allocate(10);
+ parcBufferComposer_PutString(composer, CCNxNameLabel_InterestPayloadId);
+ parcBufferComposer_PutChar(composer, '=');
+
+ PARCBufferComposer *uriComposer = parcBufferComposer_Allocate(10);
+ parcBufferComposer_PutChar(uriComposer, type);
+ parcBufferComposer_PutString(uriComposer, test);
+ PARCBuffer *producedBuffer = parcBufferComposer_ProduceBuffer(uriComposer);
+ PARCURISegment *uriSegment = parcURISegment_CreateFromBuffer(producedBuffer);
+ parcBuffer_Release(&producedBuffer);
+ parcBufferComposer_Release(&uriComposer);
+ parcURISegment_BuildString(uriSegment, composer);
+ parcURISegment_Release(&uriSegment);
+ char *expect = parcBufferComposer_ToString(composer);
+ parcBufferComposer_Release(&composer);
+
+ assertTrue(strcmp(expect, result) == 0, "Expect test and result strings to be the same.");
+
+ parcMemory_Deallocate((void **) &result);
+ parcMemory_Deallocate((void **) &expect);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestPayloadId_GetNameSegment)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ uint8_t type = data->type;
+ PARCBuffer *value = parcBuffer_Acquire(data->value);
+ CCNxInterestPayloadId *ipId = ccnxInterestPayloadId_Create(value, type);
+
+ CCNxNameSegment *segment = ccnxNameSegment_Acquire(ccnxInterestPayloadId_GetNameSegment(ipId));
+ ccnxInterestPayloadId_Release(&ipId);
+
+ PARCBufferComposer *composer = parcBufferComposer_Allocate(parcBuffer_Capacity(value) + 1);
+ parcBufferComposer_PutUint8(composer, type);
+ parcBufferComposer_PutBuffer(composer, value);
+ PARCBuffer *testValue = parcBufferComposer_ProduceBuffer(composer);
+ parcBufferComposer_Release(&composer);
+ parcBuffer_Release(&value);
+ CCNxNameSegment *testSegment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_PAYLOADID, testValue);
+ parcBuffer_Release(&testValue);
+ assertTrue(ccnxNameSegment_Equals(segment, testSegment), "Expect GetAsNameSegment result to match test NameSegment");
+
+ ccnxNameSegment_Release(&segment);
+ ccnxNameSegment_Release(&testSegment);
+}
+
+LONGBOW_TEST_FIXTURE(Error)
+{
+ LONGBOW_RUN_TEST_CASE(Error, ccnxInterestPayloadId__CreateFromNameSegment_NotFound);
+}
+
+typedef struct {
+ CCNxName *name;
+} TestDataError;
+
+LONGBOW_TEST_FIXTURE_SETUP(Error)
+{
+ _originalMemoryProvider = parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+
+ TestDataError *data = parcMemory_AllocateAndClear(sizeof(TestDataError));
+ assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestDataError));
+ data->name = ccnxName_CreateFromCString("lci:/segment1/segment2/segment3");
+ longBowTestCase_SetClipBoardData(testCase, data);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Error)
+{
+ TestDataError *data = longBowTestCase_GetClipBoardData(testCase);
+ ccnxName_Release(&data->name);
+ parcMemory_Deallocate((void **) &data);
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestRunner_GetName(testRunner), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ parcMemory_SetInterface(_originalMemoryProvider);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE_EXPECTS(Error, ccnxInterestPayloadId__CreateFromNameSegment_NotFound, .event = &LongBowAssertEvent)
+{
+ TestDataError *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxNameSegment *nameSegment = ccnxName_GetSegment(data->name, 0);
+ CCNxInterestPayloadId *result =
+ _ccnxInterestPayloadId_CreateFromNameSegment(nameSegment);
+ assertNull(result, "Expect an assert event or NULL");
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_InterestPayloadId);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_InterestReturn.c b/libccnx-common/ccnx/common/test/test_ccnx_InterestReturn.c
new file mode 100755
index 00000000..79e27994
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_InterestReturn.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../ccnx_InterestReturn.c"
+#include "../ccnx_Interest.h"
+#include <parc/algol/parc_SafeMemory.h>
+#include <LongBow/unit-test.h>
+
+#include <ccnx/common/ccnx_Interest.h>
+#include <ccnx/common/ccnx_InterestReturn.h>
+#include <ccnx/common/ccnx_PayloadType.h>
+
+typedef struct test_data {
+ CCNxTlvDictionary *interest;
+ CCNxInterestInterface *interestImpl;
+
+ CCNxName *name;
+ PARCBuffer *keyid;
+ PARCBuffer *contentObjectHash;
+ PARCBuffer *payload;
+
+ // allocated data
+ uint8_t keyidArray[32];
+ uint8_t contentObjectHashArray[32];
+ uint8_t payloadArray[128];
+
+ uint32_t lifetime;
+ uint32_t hoplimit;
+ CCNxPayloadType payloadType;
+} TestData;
+
+
+LONGBOW_TEST_RUNNER(ccnx_InterestReturnV1)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_InterestReturnV1)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_InterestReturnV1)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// ========================================================================================
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnV1_Create);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnV1_GetReturnCode);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnV1_AcquireRelease);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnV1_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnV1_NotEquals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnV1_ToString);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxInterestReturnV1_GetInterestFields);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
+ assertNotNull(data, "parcMemory_AllocateAndClear(%lu) returned NULL", sizeof(TestData));
+ data->name = ccnxName_CreateFromCString("lci:/once/upon/a/time");
+
+ for (int i = 0; i < 32; i++) {
+ data->keyidArray[i] = i * 7;
+ data->contentObjectHashArray[i] = i * 11;
+ }
+
+ for (int i = 0; i < 128; i++) {
+ data->payloadArray[i] = i * 13;
+ }
+
+ data->interestImpl = &CCNxInterestFacadeV1_Implementation;
+ data->keyid = parcBuffer_Wrap(data->keyidArray, 32, 0, 32);
+ data->contentObjectHash = parcBuffer_Wrap(data->contentObjectHashArray, 32, 0, 32);
+ data->payloadType = CCNxPayloadType_DATA;
+ data->payload = parcBuffer_Wrap(data->payloadArray, 128, 0, 128);
+
+ data->lifetime = 900;
+ data->hoplimit = 77;
+
+ data->interest = ccnxInterest_CreateWithImpl(data->interestImpl,
+ data->name,
+ data->lifetime,
+ data->keyid,
+ data->contentObjectHash,
+ data->hoplimit);
+
+ ccnxInterest_SetPayload(data->interest, data->payload);
+
+ longBowTestCase_SetClipBoardData(testCase, data);
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ ccnxName_Release(&data->name);
+ parcBuffer_Release(&data->keyid);
+ parcBuffer_Release(&data->contentObjectHash);
+ parcBuffer_Release(&data->payload);
+ ccnxTlvDictionary_Release(&data->interest);
+
+ parcMemory_Deallocate((void **) &data);
+
+ if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) {
+ printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding());
+ return LONGBOW_STATUS_TEARDOWN_FAILED;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestReturnV1_Create)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxInterestReturn *interestReturn =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute);
+
+ ccnxInterestReturn_AssertValid(interestReturn);
+
+ //assertTrue(ccnxInterestReturn_IsValid(interestReturn), "InterestReturn is not valid");
+ ccnxTlvDictionary_Release(&interestReturn);
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxInterestReturnV1_AcquireRelease)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxInterestReturn *interestReturn =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute);
+
+ assertNotNull(interestReturn, "Expect non-NULL interestReturn");
+
+ CCNxInterestReturn *testInterestReturn = ccnxInterestReturn_Acquire(interestReturn);
+ assertNotNull(testInterestReturn, "Expected a non-NULL testInterestReturn");
+
+ ccnxInterestReturn_Release(&testInterestReturn);
+ assertNull(testInterestReturn, "Expected a NULL testInterestReturn");
+
+ ccnxInterestReturn_Release(&interestReturn);
+ assertNull(interestReturn, "Expected a NULL testInterestReturn");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestReturnV1_Equals)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxInterestReturn *interestReturn =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute);
+ assertTrue(ccnxInterestReturn_Equals(interestReturn, interestReturn), "Expect same interestReturn pointers to be equal");
+
+ CCNxInterestReturn *acquiredIR = ccnxInterestReturn_Acquire(interestReturn);
+ assertTrue(ccnxInterestReturn_Equals(interestReturn, acquiredIR), "Expect acquired interestReturn to be equal to original");
+ ccnxInterestReturn_Release(&acquiredIR);
+
+ CCNxInterestReturn *identicalIR =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute);
+ assertTrue(ccnxInterestReturn_Equals(interestReturn, identicalIR), "Expect identical interestReturn to be equal to original");
+
+ ccnxInterestReturn_Release(&identicalIR);
+ ccnxInterestReturn_Release(&interestReturn);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestReturnV1_NotEquals)
+{
+ assertFalse(ccnxInterestReturn_Equals(NULL, NULL), "Expect two NULL interests to not be equal");
+
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxInterestReturn *interestReturn =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute);
+ assertFalse(ccnxInterestReturn_Equals(interestReturn, NULL), "Expect a NULL interest to not be equal");
+
+ CCNxInterestReturn *testIR =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_MTUTooLarge);
+ assertFalse(ccnxInterestReturn_Equals(interestReturn, testIR), "Expect interestReturn's with different return codes to be !=");
+
+ ccnxInterestReturn_Release(&testIR);
+ ccnxInterestReturn_Release(&interestReturn);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestReturnV1_ToString)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxInterestReturn *interestReturn =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute);
+
+ const char *string = ccnxInterestReturn_ToString(interestReturn);
+ assertNotNull(string, "Expected non-null result from ccnxInterestReturn_ToString.");
+
+ parcMemory_Deallocate((void **) &string);
+
+ ccnxInterestReturn_Release(&interestReturn);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestReturnV1_GetReturnCode)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxInterestReturn *interestReturn =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute);
+
+ CCNxInterestReturn_ReturnCode code =
+ ccnxInterestReturn_GetReturnCode(interestReturn);
+
+ assertTrue((CCNxInterestReturn_ReturnCode_NoRoute == code), "InterestReturn wrong Return Code");
+ ccnxInterestReturn_Release(&interestReturn);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxInterestReturnV1_GetInterestFields)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxInterestReturn *interestReturn =
+ ccnxInterestReturn_Create(data->interest, CCNxInterestReturn_ReturnCode_NoRoute);
+
+ CCNxName *name = ccnxInterest_GetName(interestReturn);
+ assertTrue(ccnxName_Equals(name, data->name), "Names do not match")
+ {
+ printf("\ngot : \n"); ccnxName_Display(name, 3);
+ printf("\nexpected: \n"); ccnxName_Display(data->name, 3);
+ }
+
+ uint32_t hopLimit = ccnxInterest_GetHopLimit(interestReturn);
+ assertTrue(hopLimit == data->hoplimit, "Wrong hoplimit: got %u expected %u", hopLimit, data->hoplimit);
+
+ uint32_t lifetime = (uint32_t) ccnxInterest_GetLifetime(interestReturn);
+ assertTrue(lifetime == data->lifetime, "Wrong lifetime: got %u expected %u", lifetime, data->lifetime);
+
+ PARCBuffer *buff = ccnxInterest_GetKeyIdRestriction(interestReturn);
+ assertTrue(parcBuffer_Equals(buff, data->keyid), "KeyIDs do not match")
+ {
+ printf("\ngot : \n"); parcBuffer_Display(buff, 3);
+ printf("\nexpected: \n"); parcBuffer_Display(data->keyid, 3);
+ }
+
+ buff = ccnxInterest_GetPayload(interestReturn);
+ assertTrue(parcBuffer_Equals(buff, data->payload), "Payloads do not match")
+ {
+ printf("\ngot : \n"); parcBuffer_Display(buff, 3);
+ printf("\nexpected: \n"); parcBuffer_Display(data->payload, 3);
+ }
+
+ ccnxInterestReturn_Release(&interestReturn);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_InterestReturnV1);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_Key.c b/libccnx-common/ccnx/common/test/test_ccnx_Key.c
new file mode 100755
index 00000000..c1bd5ed2
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_Key.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+#include <config.h>
+#include "../ccnx_Key.c"
+#include <LongBow/unit-test.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(ccnx_Key)
+{
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Local);
+}
+
+LONGBOW_TEST_RUNNER_SETUP(ccnx_Key)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_Key)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKey_CreateRelease);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKey_CreateFromHexString);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKey_FromByteBuffer);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKey_ToString);
+}
+
+typedef struct {
+ char *hexString;
+} TestData;
+
+static TestData*
+commonSetup()
+{
+ char *hexString = "30819F300D06092A864886F70D010101050003818D0030818902818100A826C09E01FF4970428213C96312B46050514FD5F87E670A4784C75D8B23CD073B1CBEF328E538584E442A769DF77299192BCF3603F50F14C5664994250E5C24DF47B86EA5C7CA99B3584E9A63BC5993569FF3612C71AD46A088CDC7346B9BE021D4CA1764CF5434F993E6120363C551E2979BDB3F0345B4994BCED9CB260EEB0203010001";
+
+ TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
+ assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData));
+ data->hexString = parcMemory_StringDuplicate(hexString, strlen(hexString));
+ return data;
+}
+
+static void
+commonTearDown(TestData *data)
+{
+ parcMemory_Deallocate((void **) &(data->hexString));
+ parcMemory_Deallocate((void **) &data);
+}
+
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ TestData *data = commonSetup();
+ longBowTestCase_SetClipBoardData(testCase, data);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ commonTearDown(data);
+
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxKey_FromByteBuffer)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ PARCBuffer *hexBuf = parcBuffer_ParseHexString(data->hexString);
+ CCNxKey *key = ccnxKey_Create(hexBuf);
+ parcBuffer_Release(&hexBuf);
+ ccnxKey_Release(&key);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKey_CreateRelease)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxKey *key = ccnxKey_CreateFromHexString(data->hexString);
+ ccnxKey_AssertValid(key);
+
+ char *string = ccnxKey_ToString(key);
+
+ ccnxKey_Release(&key);
+ assertNull(key, "Key was not nulled out after Release()");
+
+ parcMemory_Deallocate((void **) &string);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKey_CreateFromHexString)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxKey *key = ccnxKey_CreateFromHexString(data->hexString);
+ ccnxKey_AssertValid(key);
+
+ char *string = ccnxKey_ToHexString(key);
+
+ assertTrue(strcasecmp(data->hexString, string) == 0,
+ "Expected '%s' actual '%s'", data->hexString, string);
+
+ ccnxKey_Release(&key);
+ assertNull(key, "Key was not nulled out after Release()");
+
+ parcMemory_Deallocate((void **) &string);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKey_ToString)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ CCNxKey *key = ccnxKey_CreateFromHexString(data->hexString);
+ ccnxKey_AssertValid(key);
+
+ char *string = ccnxKey_ToString(key);
+
+ ccnxKey_Release(&key);
+ assertNull(key, "Key was not nulled out after Release()");
+
+ parcMemory_Deallocate((void **) &string);
+}
+
+LONGBOW_TEST_FIXTURE(Local)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Local)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Local)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_Key);
+ exit(longBowMain(argc, argv, testRunner, NULL));
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_KeyLocator.c b/libccnx-common/ccnx/common/test/test_ccnx_KeyLocator.c
new file mode 100755
index 00000000..3e877179
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_KeyLocator.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../ccnx_KeyLocator.c"
+
+#include <parc/algol/parc_SafeMemory.h>
+#include <LongBow/unit-test.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(ccnx_KeyLocator)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Local);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_KeyLocator)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_KeyLocator)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_Copy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_Destroy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_FromKey);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_FromKeyLink);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_GetKey);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_GetKeyName);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_GetType);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_IsKey);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_IsKeyName);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxKeyLocator_ToString);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_Copy)
+{
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+
+ CCNxKeyLocator *copy = ccnxKeyLocator_Copy(keyLocator);
+ assertTrue(ccnxKeyLocator_Equals(copy, keyLocator), "Expected orig and copy to be the same");
+
+ ccnxKeyLocator_Release(&keyLocator);
+ ccnxKeyLocator_Release(&copy);
+
+ ccnxName_Release(&keyURIName);
+ ccnxLink_Release(&keyLink);
+
+ // Try FromHexString, too, for yucks.
+ PARCBuffer *keyBuffer = parcBuffer_WrapCString("hello world");
+ PARCKeyId *keyId = parcKeyId_Create(keyBuffer);
+ PARCKey *key = parcKey_CreateFromDerEncodedPublicKey(keyId, PARCSigningAlgorithm_RSA, keyBuffer);
+ parcKeyId_Release(&keyId);
+ parcBuffer_Release(&keyBuffer);
+ CCNxKeyLocator *keyLocator2 = ccnxKeyLocator_CreateFromKey(key);
+
+ CCNxKeyLocator *copy2 = ccnxKeyLocator_Copy(keyLocator2);
+ assertTrue(ccnxKeyLocator_Equals(copy, keyLocator), "Expected orig and copy to be the same");
+
+ parcKey_Release(&key);
+ ccnxKeyLocator_Release(&keyLocator2);
+ ccnxKeyLocator_Release(&copy2);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_Destroy)
+{
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+
+ ccnxKeyLocator_Release(&keyLocator);
+ assertNull(keyLocator, "keyLocator was not nulled out by Release()");
+
+ ccnxLink_Release(&keyLink);
+ ccnxName_Release(&keyURIName);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_Equals)
+{
+ char *hexString = "ABCDEF1234";
+ PARCBuffer *keyBuffer = parcBuffer_WrapCString(hexString);
+ PARCKeyId *keyId = parcKeyId_Create(keyBuffer);
+ PARCKey *key1 = parcKey_CreateFromDerEncodedPublicKey(keyId, PARCSigningAlgorithm_RSA, keyBuffer);
+ CCNxKeyLocator *keyLocator1 = ccnxKeyLocator_CreateFromKey(key1);
+ parcKeyId_Release(&keyId);
+ parcBuffer_Release(&keyBuffer);
+
+ CCNxKeyLocator *keyLocator1Copy = ccnxKeyLocator_Copy(keyLocator1);
+
+ PARCBuffer *keyBuffer2 = parcBuffer_WrapCString(hexString);
+ PARCKeyId *keyId2 = parcKeyId_Create(keyBuffer2);
+ PARCKey *key2 = parcKey_CreateFromDerEncodedPublicKey(keyId2, PARCSigningAlgorithm_RSA, keyBuffer2);
+ CCNxKeyLocator *keyLocator2 = ccnxKeyLocator_CreateFromKey(key2);
+ parcBuffer_Release(&keyBuffer2);
+ parcKeyId_Release(&keyId2);
+
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ CCNxKeyLocator *keyLocatorDiff = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator1);
+ ccnxKeyLocator_AssertValid(keyLocator1Copy);
+ ccnxKeyLocator_AssertValid(keyLocator2);
+ ccnxKeyLocator_AssertValid(keyLocatorDiff);
+
+ assertEqualsContract(ccnxKeyLocator_Equals, keyLocator1, keyLocator1Copy, keyLocator2, keyLocatorDiff);
+
+ parcKey_Release(&key1);
+ ccnxKeyLocator_Release(&keyLocator1);
+ ccnxKeyLocator_Release(&keyLocator1Copy);
+
+ parcKey_Release(&key2);
+ ccnxKeyLocator_Release(&keyLocator2);
+
+ ccnxName_Release(&keyURIName);
+ ccnxLink_Release(&keyLink);
+ ccnxKeyLocator_Release(&keyLocatorDiff);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_FromKey)
+{
+ char *hexString = "ABCDEF1234";
+ PARCBuffer *keyBuffer = parcBuffer_WrapCString(hexString);
+ PARCKeyId *keyId = parcKeyId_Create(keyBuffer);
+
+ PARCKey *key = parcKey_CreateFromDerEncodedPublicKey(keyId, PARCSigningAlgorithm_RSA, keyBuffer);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKey(key);
+ parcKeyId_Release(&keyId);
+ parcBuffer_Release(&keyBuffer);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+
+ ccnxKeyLocator_Release(&keyLocator);
+ parcKey_Release(&key);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_FromKeyLink)
+{
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+
+ ccnxKeyLocator_Release(&keyLocator);
+ ccnxName_Release(&keyURIName);
+ ccnxLink_Release(&keyLink);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_GetKey)
+{
+ char *hexString = "ABCDEF1234";
+ PARCBuffer *keyBuffer = parcBuffer_WrapCString(hexString);
+ PARCKeyId *keyId = parcKeyId_Create(keyBuffer);
+
+ PARCKey *key = parcKey_CreateFromDerEncodedPublicKey(keyId, PARCSigningAlgorithm_RSA, keyBuffer);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKey(key);
+
+ parcKeyId_Release(&keyId);
+ parcBuffer_Release(&keyBuffer);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+ PARCKey *actual = ccnxKeyLocator_GetKey(keyLocator);
+ assertTrue(actual == key, "Actual certificate didn't match expected");
+
+ ccnxKeyLocator_Release(&keyLocator);
+ parcKey_Release(&key);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_GetKeyName)
+{
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name/test");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+ const CCNxName *actual = ccnxLink_GetName(ccnxKeyLocator_GetKeyLink(keyLocator));
+ assertTrue(ccnxName_Equals(actual, keyURIName), "Actual keyName did not match the one returned by GetKeyName()");
+
+ ccnxKeyLocator_Release(&keyLocator);
+ ccnxName_Release(&keyURIName);
+ ccnxLink_Release(&keyLink);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_GetType)
+{
+ // Try FromKey
+ char *hexString = "ABCDEF1234";
+ PARCBuffer *keyBuffer = parcBuffer_WrapCString(hexString);
+ PARCKeyId *keyId = parcKeyId_Create(keyBuffer);
+
+ PARCKey *key = parcKey_CreateFromDerEncodedPublicKey(keyId, PARCSigningAlgorithm_RSA, keyBuffer);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKey(key);
+ parcKeyId_Release(&keyId);
+ parcBuffer_Release(&keyBuffer);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+ assertTrue(ccnxKeyLocator_GetType(keyLocator) == CCNxKeyLocatorType_Key, "Actual certificate type didn't match expected type");
+
+ ccnxKeyLocator_Release(&keyLocator);
+ parcKey_Release(&key);
+
+ // Try KeyName
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name/test");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ keyLocator = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+ assertTrue(ccnxKeyLocator_GetType(keyLocator) == CCNxKeyLocatorType_Link, "Actual certificate type didn't match expected type");
+ assertFalse(ccnxKeyLocator_GetType(keyLocator) == CCNxKeyLocatorType_Key, "Actual certificate type didn't match expected type");
+
+ ccnxKeyLocator_Release(&keyLocator);
+ ccnxName_Release(&keyURIName);
+ ccnxLink_Release(&keyLink);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_IsKey)
+{
+ char *hexString = "ABCDEF1234";
+ PARCBuffer *keyBuffer = parcBuffer_WrapCString(hexString);
+ PARCKeyId *keyId = parcKeyId_Create(keyBuffer);
+
+ PARCKey *key = parcKey_CreateFromDerEncodedPublicKey(keyId, PARCSigningAlgorithm_RSA, keyBuffer);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKey(key);
+ parcKeyId_Release(&keyId);
+ parcBuffer_Release(&keyBuffer);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+ assertTrue(ccnxKeyLocator_IsKey(keyLocator), "Expected Iskey to be true");
+ assertFalse(ccnxKeyLocator_IsKeyLink(keyLocator), "Expected IsKeyLink to be false");
+
+ ccnxKeyLocator_Release(&keyLocator);
+ parcKey_Release(&key);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_IsKeyName)
+{
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name/test");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+ assertFalse(ccnxKeyLocator_IsKey(keyLocator), "Expected Iskey to be false");
+ assertTrue(ccnxKeyLocator_IsKeyLink(keyLocator), "Expected IsKeyLink to be true");
+
+ ccnxKeyLocator_Release(&keyLocator);
+ ccnxName_Release(&keyURIName);
+ ccnxLink_Release(&keyLink);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxKeyLocator_ToString)
+{
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name/test");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+
+ char *actualString = ccnxKeyLocator_ToString(keyLocator);
+
+ assertTrue(0 == strncmp("KeyLocator", actualString, strlen("KeyLocator")), "ToString() did not return the expected prefix");
+
+ parcMemory_Deallocate((void **) &actualString);
+
+ ccnxLink_Release(&keyLink);
+ ccnxName_Release(&keyURIName);
+ ccnxKeyLocator_Release(&keyLocator);
+}
+
+LONGBOW_TEST_FIXTURE(Local)
+{
+ LONGBOW_RUN_TEST_CASE(Local, ccnxKeyLocator_Create);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Local)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Local)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Local, ccnxKeyLocator_Create)
+{
+ CCNxName *keyURIName = ccnxName_CreateFromCString("lci://name");
+ CCNxLink *keyLink = ccnxLink_Create(keyURIName, NULL, NULL);
+ CCNxKeyLocator *keyLocator = ccnxKeyLocator_CreateFromKeyLink(keyLink);
+
+ ccnxKeyLocator_AssertValid(keyLocator);
+
+ ccnxKeyLocator_Release(&keyLocator);
+ ccnxName_Release(&keyURIName);
+ ccnxLink_Release(&keyLink);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_KeyLocator);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_KeystoreUtilities.c b/libccnx-common/ccnx/common/test/test_ccnx_KeystoreUtilities.c
new file mode 100644
index 00000000..0ab770a5
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_KeystoreUtilities.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../ccnx_KeystoreUtilities.c"
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/security/parc_Security.h>
+
+#include <errno.h>
+#include <ftw.h>
+
+typedef struct test_data {
+ char dirname[1024];
+} TestData;
+
+static int
+deleteEntry(const char *fpath, const struct stat *sb,
+ int tflag, struct FTW *ftwbuf)
+{
+ if (tflag == FTW_DP) {
+ // directory in post-order
+ rmdir(fpath);
+ } else {
+ unlink(fpath);
+ }
+ return 0; /* To tell nftw() to continue */
+}
+
+__attribute__((unused))
+static void
+recursiveDelete(const char *path)
+{
+ // only allow under tmp
+ assertTrue(strncmp(path, "/tmp/", 5) == 0, "Path must begin with /tmp/: %s", path);
+ // dont allow ".."
+ assertNull(strstr(path, ".."), "Path cannot have .. in it: %s", path);
+
+ // depth first, dont't follow symlinks
+ int flags = FTW_DEPTH | FTW_PHYS;
+
+ // maximum 20 fds open at a time
+ int max_fd = 20;
+
+ int failure = nftw(path, deleteEntry, max_fd, flags);
+ assertFalse(failure, "Error on recursive delete: (%d) %s", errno, strerror(errno));
+}
+
+static TestData *
+commonSetup(const char *testCaseName)
+{
+ TestData *data = parcMemory_AllocateAndClear(sizeof(TestData));
+ assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData));
+ sprintf(data->dirname, "/tmp/%s.%d", testCaseName, getpid());
+ mkdir(data->dirname, S_IRWXU | S_IRWXG);
+ setenv("HOME", data->dirname, 1);
+
+ return data;
+}
+
+static void
+commonTeardown(TestData **dataPtr)
+{
+ TestData *data = *dataPtr;
+
+ recursiveDelete(data->dirname);
+ parcMemory_Deallocate((void **) &data);
+ *dataPtr = NULL;
+}
+
+LONGBOW_TEST_RUNNER(ccnx_KeystoreUtilities)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Local);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_KeystoreUtilities)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_KeystoreUtilities)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ TestData *data = commonSetup(longBowTestCase_GetName(testCase));
+ longBowTestCase_SetClipBoardData(testCase, data);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ commonTeardown(&data);
+ if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) {
+ printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding());
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Local)
+{
+ LONGBOW_RUN_TEST_CASE(Local, ccnxKeystoreUtilities_ConstructPath);
+ LONGBOW_RUN_TEST_CASE(Local, ccnxKeystoreUtilities_HomeDirectoryFromEnv);
+ LONGBOW_RUN_TEST_CASE(Local, ccnxKeystoreUtilities_HomeDirectoryFromPasswd);
+
+ LONGBOW_RUN_TEST_CASE(Local, ccnxKeystoreUtilities_OpenFromHomeDirectory_Missing);
+
+ LONGBOW_RUN_TEST_CASE(Local, ccnxKeystoreUtilities_OpenFromHomeDirectory_Newfile);
+ LONGBOW_RUN_TEST_CASE(Local, ccnxKeystoreUtilities_OpenFromHomeDirectory_Oldfile);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Local)
+{
+ parcSecurity_Init();
+
+ TestData *data = commonSetup(longBowTestCase_GetName(testCase));
+ longBowTestCase_SetClipBoardData(testCase, data);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Local)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+ commonTeardown(&data);
+
+ parcSecurity_Fini();
+
+ if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) {
+ printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding());
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Local, ccnxKeystoreUtilities_ConstructPath)
+{
+ const char *dir = "/some/where";
+ const char *file = "else";
+ const char *truth = "/some/where/else";
+
+ char *test = ccnxKeystoreUtilities_ConstructPath(dir, file);
+ assertTrue(strcmp(truth, test) == 0, "Wrong path, expected %s got %s", truth, test);
+ parcMemory_Deallocate((void **) &test);
+}
+
+LONGBOW_TEST_CASE(Local, ccnxKeystoreUtilities_HomeDirectoryFromEnv)
+{
+ TestData *data = longBowTestCase_GetClipBoardData(testCase);
+
+ char *dir = ccnxKeystoreUtilities_HomeDirectoryFromEnv();
+ assertNotNull(dir, "Did not get HOME variable from environment");
+ assertTrue(strcmp(dir, data->dirname) == 0, "HOME directory not correct, expecting %s got %s\n", data->dirname, dir);
+ parcMemory_Deallocate((void **) &dir);
+}
+
+LONGBOW_TEST_CASE(Local, ccnxKeystoreUtilities_HomeDirectoryFromPasswd)
+{
+ char *dir = ccnxKeystoreUtilities_HomeDirectoryFromPasswd();
+ assertNotNull(dir, "Did not get HOME variable from environment");
+ parcMemory_Deallocate((void **) &dir);
+}
+
+/**
+ * Create a temporary directory, set HOME to it, then try to open, but do
+ * not create the keystore. should return NULL.
+ */
+LONGBOW_TEST_CASE(Local, ccnxKeystoreUtilities_OpenFromHomeDirectory_Missing)
+{
+ KeystoreParams *params = ccnxKeystoreUtilities_OpenFromHomeDirectory("abcd");
+ assertNull(params, "Signer should have been null opening from non-existent keystore");
+}
+
+
+/**
+ * Create a keystore with the old default name in the old location
+ */
+LONGBOW_TEST_CASE(Local, ccnxKeystoreUtilities_OpenFromHomeDirectory_Oldfile)
+{
+ char *homedir = ccnxKeystoreUtilities_GetHomeDirectory();
+ char *ccnxdir = ccnxKeystoreUtilities_ConstructPath(homedir, ".ccnx");
+ mkdir(ccnxdir, 0700);
+ char *path = ccnxKeystoreUtilities_ConstructPath(ccnxdir, ".ccnx_keystore");
+
+ bool success = parcPkcs12KeyStore_CreateFile(path, "1234", "ccnxuser", 1024, 365);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile() failed.");
+
+ KeystoreParams *signer = ccnxKeystoreUtilities_OpenFromHomeDirectory("1234");
+ assertNotNull(signer, "Signer should be non-null opening from a file we just created");
+ keystoreParams_Destroy(&signer);
+
+ parcMemory_Deallocate((void **) &path);
+ parcMemory_Deallocate((void **) &ccnxdir);
+ parcMemory_Deallocate((void **) &homedir);
+}
+
+/**
+ * Create a keystore with the new default name in the old location
+ */
+LONGBOW_TEST_CASE(Local, ccnxKeystoreUtilities_OpenFromHomeDirectory_Newfile)
+{
+ char *homedir = ccnxKeystoreUtilities_GetHomeDirectory();
+ char *ccnxdir = ccnxKeystoreUtilities_ConstructPath(homedir, ".ccnx");
+ mkdir(ccnxdir, 0700);
+ char *path = ccnxKeystoreUtilities_ConstructPath(ccnxdir, ".ccnx_keystore.p12");
+
+ bool success = parcPkcs12KeyStore_CreateFile(path, "1234", "ccnxuser", 1024, 365);
+ assertTrue(success, "parcPkcs12KeyStore_CreateFile() failed.");
+
+ KeystoreParams *signer = ccnxKeystoreUtilities_OpenFromHomeDirectory("1234");
+ assertNotNull(signer, "Signer should be non-null opening from a file we just created");
+ keystoreParams_Destroy(&signer);
+
+ parcMemory_Deallocate((void **) &path);
+ parcMemory_Deallocate((void **) &ccnxdir);
+ parcMemory_Deallocate((void **) &homedir);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_KeystoreUtilities);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_Link.c b/libccnx-common/ccnx/common/test/test_ccnx_Link.c
new file mode 100755
index 00000000..87105468
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_Link.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+
+#include <ccnx/common/ccnx_Link.c>
+
+#include <LongBow/unit-test.h>
+
+#include <parc/algol/parc_Object.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/algol/parc_ArrayList.h>
+#include <parc/testing/parc_ObjectTesting.h>
+
+LONGBOW_TEST_RUNNER(ccnx_Link)
+{
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_Link)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_Link)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_Create_Full);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_Create_EmptyKeyID);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_Create_EmptyContentObjectHash);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_Create_EmptyBoth);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_AcquireRelease);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_GetName);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_GetKeyID);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_GetContentObjectHash);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_Create_ToString);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxLink_Equals);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_Create_Full)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = parcBuffer_Allocate(10);
+ PARCBuffer *contentObjectHash = parcBuffer_Allocate(10);
+
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+
+ assertNotNull(object, "Expected non-null return value.");
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_Create_EmptyKeyID)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = NULL;
+ PARCBuffer *contentObjectHash = parcBuffer_Allocate(10);
+
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+
+ assertNotNull(object, "Expected non-null return value.");
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&contentObjectHash);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_Create_EmptyContentObjectHash)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = parcBuffer_Allocate(10);
+ PARCBuffer *contentObjectHash = NULL;
+
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+
+ assertNotNull(object, "Expected non-null return value.");
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_Create_EmptyBoth)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = NULL;
+ PARCBuffer *contentObjectHash = NULL;
+
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+
+ assertNotNull(object, "Expected non-null return value.");
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_AcquireRelease)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = parcBuffer_Allocate(10);
+ PARCBuffer *contentObjectHash = parcBuffer_Allocate(10);
+
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+ parcObjectTesting_AssertAcquireReleaseContract(ccnxLink_Acquire, object);
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_GetName)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = parcBuffer_Allocate(10);
+ PARCBuffer *contentObjectHash = parcBuffer_Allocate(10);
+
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+
+ const CCNxName *actualName = ccnxLink_GetName(object);
+ assertNotNull(actualName, "Expected non-null return value.");
+ assertTrue(ccnxName_Equals(name, actualName), "Expected the same name back");
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_GetKeyID)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = parcBuffer_Allocate(10);
+ PARCBuffer *contentObjectHash = parcBuffer_Allocate(20);
+
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+
+ PARCBuffer *buffer = ccnxLink_GetKeyID(object);
+ assertNotNull(buffer, "Expected non-null return value.");
+ assertTrue(parcBuffer_Capacity(buffer) == 10, "Expected the same buffer size back");
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_GetContentObjectHash)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = parcBuffer_Allocate(10);
+ PARCBuffer *contentObjectHash = parcBuffer_Allocate(20);
+
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+
+ PARCBuffer *buffer = ccnxLink_GetContentObjectHash(object);
+ assertNotNull(buffer, "Expected non-null return value.");
+ assertTrue(parcBuffer_Capacity(buffer) == 20, "Expected the same buffer size back");
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_Equals)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = parcBuffer_Allocate(10);
+ PARCBuffer *contentObjectHash = parcBuffer_Allocate(20);
+ CCNxLink *x = ccnxLink_Create(name, keyId, contentObjectHash);
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+
+ name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ keyId = parcBuffer_Allocate(10);
+ contentObjectHash = parcBuffer_Allocate(20);
+ CCNxLink *y = ccnxLink_Create(name, keyId, contentObjectHash);
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+
+ name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ keyId = parcBuffer_Allocate(10);
+ contentObjectHash = parcBuffer_Allocate(20);
+ CCNxLink *z = ccnxLink_Create(name, keyId, contentObjectHash);
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+
+ name = ccnxName_CreateFromCString("lci:/foo/bar/othername");
+ keyId = parcBuffer_Allocate(10);
+ contentObjectHash = parcBuffer_Allocate(20);
+ CCNxLink *unequal1 = ccnxLink_Create(name, keyId, contentObjectHash);
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+
+ name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ keyId = NULL;
+ contentObjectHash = parcBuffer_Allocate(20);
+ CCNxLink *unequal2 = ccnxLink_Create(name, keyId, contentObjectHash);
+ ccnxName_Release(&name);
+ parcBuffer_Release(&contentObjectHash);
+
+ name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ keyId = parcBuffer_Allocate(10);
+ contentObjectHash = NULL;
+ CCNxLink *unequal3 = ccnxLink_Create(name, keyId, contentObjectHash);
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+
+ assertEqualsContract(ccnxLink_Equals, x, y, z, unequal1, unequal2, unequal3);
+
+ ccnxLink_Release(&x);
+ ccnxLink_Release(&y);
+ ccnxLink_Release(&z);
+ ccnxLink_Release(&unequal1);
+ ccnxLink_Release(&unequal2);
+ ccnxLink_Release(&unequal3);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxLink_Create_ToString)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/foo/bar/name");
+ PARCBuffer *keyId = parcBuffer_Allocate(10);
+ PARCBuffer *contentObjectHash = parcBuffer_Allocate(20);
+ CCNxLink *object = ccnxLink_Create(name, keyId, contentObjectHash);
+
+ char *string = ccnxLink_ToString(object);
+ assertNotNull(string, "Expected non-null string.");
+ parcMemory_Deallocate((void **) &string);
+
+ ccnxLink_Release(&object);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&keyId);
+ parcBuffer_Release(&contentObjectHash);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_Link);
+ int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_Manifest.c b/libccnx-common/ccnx/common/test/test_ccnx_Manifest.c
new file mode 100755
index 00000000..583c9a79
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_Manifest.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../ccnx_Manifest.c"
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+#include <parc/testing/parc_ObjectTesting.h>
+
+#include <ccnx/common/ccnx_Interest.h>
+
+typedef struct test_data {
+ CCNxManifest *object;
+ CCNxManifest *manifestWithNamelessGroup;
+ CCNxManifest *nameless;
+ PARCLinkedList *interestListFromGroupLocator;
+ PARCLinkedList *interestListFromManifestLocator;
+ PARCLinkedList *interestListFromOverrideLocator;
+ CCNxName *overrideLocator;
+} ManifestTestData;
+
+static ManifestTestData *
+_commonSetup(void)
+{
+ ManifestTestData *data = parcMemory_AllocateAndClear(sizeof(ManifestTestData));
+
+ data->overrideLocator = ccnxName_CreateFromCString("ccnx:/override");
+
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/my/manifest");
+ CCNxManifest *manifest = ccnxManifest_Create(name);
+ CCNxManifest *nameless = ccnxManifest_CreateNameless();
+ CCNxManifest *manifestWithNamelessGroup = ccnxManifest_Create(name);
+
+ data->interestListFromGroupLocator = parcLinkedList_Create();
+ data->interestListFromManifestLocator = parcLinkedList_Create();
+ data->interestListFromOverrideLocator = parcLinkedList_Create();
+ data->object = manifest;
+ data->nameless = nameless;
+ data->manifestWithNamelessGroup = manifestWithNamelessGroup;
+
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ CCNxManifestHashGroup *namelessGroup = ccnxManifestHashGroup_Create();
+
+ CCNxName *locator = ccnxName_CreateFromCString("ccnx:/locator");
+ ccnxManifestHashGroup_SetLocator(group, locator);
+
+ // Create pointers for the pieces of data
+ PARCBuffer *digest1 = parcBuffer_Allocate(32);
+ PARCBuffer *digest2 = parcBuffer_Allocate(32);
+ ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, digest1);
+ ccnxManifestHashGroup_AppendPointer(namelessGroup, CCNxManifestHashGroupPointerType_Data, digest1);
+ ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Manifest, digest2);
+ ccnxManifestHashGroup_AppendPointer(namelessGroup, CCNxManifestHashGroupPointerType_Data, digest2);
+
+ // Create the corresponding interests based on the three locator cases
+ // 1. The locator is inherited from the hash group
+ // 2. The locator is inherited from the manifest
+ // 3. The locator is overridden
+ CCNxInterest *interest1 = ccnxInterest_CreateSimple(locator);
+ ccnxInterest_SetContentObjectHashRestriction(interest1, digest1);
+ parcLinkedList_Append(data->interestListFromGroupLocator, interest1);
+ ccnxInterest_Release(&interest1);
+
+ interest1 = ccnxInterest_CreateSimple(name);
+ ccnxInterest_SetContentObjectHashRestriction(interest1, digest1);
+ parcLinkedList_Append(data->interestListFromManifestLocator, interest1);
+ ccnxInterest_Release(&interest1);
+
+ interest1 = ccnxInterest_CreateSimple(data->overrideLocator);
+ ccnxInterest_SetContentObjectHashRestriction(interest1, digest1);
+ parcLinkedList_Append(data->interestListFromOverrideLocator, interest1);
+ ccnxInterest_Release(&interest1);
+
+ CCNxInterest *interest2 = ccnxInterest_CreateSimple(locator);
+ ccnxInterest_SetContentObjectHashRestriction(interest2, digest2);
+ parcLinkedList_Append(data->interestListFromGroupLocator, interest2);
+ ccnxInterest_Release(&interest2);
+
+ interest2 = ccnxInterest_CreateSimple(name);
+ ccnxInterest_SetContentObjectHashRestriction(interest2, digest2);
+ parcLinkedList_Append(data->interestListFromManifestLocator, interest2);
+ ccnxInterest_Release(&interest2);
+
+ interest2 = ccnxInterest_CreateSimple(data->overrideLocator);
+ ccnxInterest_SetContentObjectHashRestriction(interest2, digest2);
+ parcLinkedList_Append(data->interestListFromOverrideLocator, interest2);
+ ccnxInterest_Release(&interest2);
+
+ ccnxName_Release(&name);
+ ccnxName_Release(&locator);
+ parcBuffer_Release(&digest1);
+ parcBuffer_Release(&digest2);
+
+ ccnxManifest_AddHashGroup(manifest, group);
+ ccnxManifest_AddHashGroup(manifestWithNamelessGroup, namelessGroup);
+ ccnxManifest_AddHashGroup(nameless, namelessGroup);
+
+ ccnxManifestHashGroup_Release(&group);
+ ccnxManifestHashGroup_Release(&namelessGroup);
+
+ return data;
+}
+
+static void
+_commonTeardown(ManifestTestData *data)
+{
+ ccnxManifest_Release(&data->object);
+ ccnxManifest_Release(&data->nameless);
+ ccnxManifest_Release(&data->manifestWithNamelessGroup);
+
+ parcLinkedList_Release(&data->interestListFromGroupLocator);
+ parcLinkedList_Release(&data->interestListFromManifestLocator);
+ parcLinkedList_Release(&data->interestListFromOverrideLocator);
+
+ ccnxName_Release(&data->overrideLocator);
+ parcMemory_Deallocate((void **) &data);
+}
+
+LONGBOW_TEST_RUNNER(ccnx_Manifest)
+{
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_Manifest)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_Manifest)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_AcquireRelease);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_Create);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_AddHashGroup);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_GetHashGroup);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_GetNumberOfHashGroups);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_GetName);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_ToString);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_CreateInterestList_OverrideLocator);
+ // LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_CreateInterestList_ManifestLocator);
+ // LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_CreateInterestList_GroupLocator);
+ // LONGBOW_RUN_TEST_CASE(Global, ccnxManifest_CreateInterestList_NoLocator);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ longBowTestCase_SetClipBoardData(testCase, _commonSetup());
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ _commonTeardown(longBowTestCase_GetClipBoardData(testCase));
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_AcquireRelease)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/my/manifest");
+ CCNxManifest *manifest = ccnxManifest_Create(name);
+ ccnxName_Release(&name);
+
+ parcObjectTesting_AssertAcquireReleaseContract(ccnxManifest_Acquire, manifest);
+
+ ccnxManifest_Release(&manifest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_Create)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/my/manifest");
+ CCNxManifest *manifest = ccnxManifest_Create(name);
+
+ assertNotNull(manifest, "Expected the Manifest to be created without errors.");
+ const CCNxName *copy = ccnxManifest_GetName(manifest);
+
+ assertTrue(ccnxName_Equals(name, copy), "Expected name to equal %s, got %s", ccnxName_ToString(name), ccnxName_ToString(copy));
+
+ ccnxName_Release(&name);
+ ccnxManifest_Release(&manifest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_AddHashGroup)
+{
+ ManifestTestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxManifest *manifest = data->object;
+
+ size_t numGroups = ccnxManifest_GetNumberOfHashGroups(manifest);
+
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ ccnxManifest_AddHashGroup(manifest, group);
+
+ size_t expected = numGroups + 1;
+ size_t actual = ccnxManifest_GetNumberOfHashGroups(manifest);
+ assertTrue(actual == expected, "Expected %zu, got %zu", expected, actual);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_GetHashGroup)
+{
+ ManifestTestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxManifest *manifest = data->object;
+
+ CCNxManifestHashGroup *group = ccnxManifest_GetHashGroupByIndex(manifest, 0);
+ CCNxName *expected = ccnxName_CreateFromCString("ccnx:/locator");
+ const CCNxName *actual = ccnxManifestHashGroup_GetLocator(group);
+ assertTrue(ccnxName_Equals(expected, actual), "Expected %s, got %s", ccnxName_ToString(expected), ccnxName_ToString(actual));
+
+ ccnxName_Release(&expected);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_GetNumberOfHashGroups)
+{
+ ManifestTestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxManifest *manifest = data->object;
+
+ size_t before = ccnxManifest_GetNumberOfHashGroups(manifest);
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ ccnxManifest_AddHashGroup(manifest, group);
+
+ size_t actual = ccnxManifest_GetNumberOfHashGroups(manifest);
+ size_t expected = before + 1;
+
+ assertTrue(expected == actual, "Expected %zu, got %zu", expected, actual);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_CreateInterestList_NoLocator)
+{
+ ManifestTestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxManifest *nameless = data->nameless;
+
+ PARCLinkedList *interestList = ccnxManifest_CreateInterestList(nameless, NULL);
+ assertTrue(parcLinkedList_Size(interestList) == 0, "Expected the interest list to be empty since there was no valid locator");
+ parcLinkedList_Release(&interestList);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_CreateInterestList_GroupLocator)
+{
+ ManifestTestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxManifest *manifest = data->object;
+
+ PARCLinkedList *interestList = ccnxManifest_CreateInterestList(manifest, NULL);
+ assertTrue(parcLinkedList_Equals(interestList, data->interestListFromGroupLocator), "Expected the interest lists to be equal");
+ parcLinkedList_Release(&interestList);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_CreateInterestList_ManifestLocator)
+{
+ ManifestTestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxManifest *manifestWithNamelessGroup = data->manifestWithNamelessGroup;
+
+ PARCLinkedList *interestList = ccnxManifest_CreateInterestList(manifestWithNamelessGroup, NULL);
+ assertTrue(parcLinkedList_Equals(interestList, data->interestListFromManifestLocator), "Expected the interest lists to be equal");
+ parcLinkedList_Release(&interestList);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_CreateInterestList_OverrideLocator)
+{
+ ManifestTestData *data = longBowTestCase_GetClipBoardData(testCase);
+ CCNxManifest *nameless = data->nameless;
+ CCNxName *overrideLocator = data->overrideLocator;
+
+ PARCLinkedList *interestList = ccnxManifest_CreateInterestList(nameless, overrideLocator);
+ assertTrue(parcLinkedList_Equals(interestList, data->interestListFromOverrideLocator), "Expected the interest lists to be equal");
+ parcLinkedList_Release(&interestList);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_GetName)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/my/manifest");
+ CCNxManifest *manifest = ccnxManifest_Create(name);
+
+ assertNotNull(manifest, "Expected the Manifest to be created without errors.");
+ const CCNxName *copy = ccnxManifest_GetName(manifest);
+
+ assertTrue(ccnxName_Equals(name, copy), "Expected name to equal %s, got %s", ccnxName_ToString(name), ccnxName_ToString(copy));
+
+ ccnxName_Release(&name);
+ ccnxManifest_Release(&manifest);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_Equals)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/my/manifest");
+ CCNxManifest *x = ccnxManifest_Create(name);
+ CCNxManifest *y = ccnxManifest_Create(name);
+ CCNxManifest *z = ccnxManifest_Create(name);
+
+ CCNxName *name1 = ccnxName_CreateFromCString("ccnx:/not/my/manifest");
+ CCNxManifest *u1 = ccnxManifest_Create(name1);
+
+ parcObjectTesting_AssertEqualsFunction(ccnxManifest_Equals, x, y, z, u1, NULL);
+
+ ccnxName_Release(&name);
+ ccnxName_Release(&name1);
+ ccnxManifest_Release(&x);
+ ccnxManifest_Release(&y);
+ ccnxManifest_Release(&z);
+ ccnxManifest_Release(&u1);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifest_ToString)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/my/manifest");
+ CCNxManifest *manifest = ccnxManifest_Create(name);
+
+ assertNotNull(manifest, "Expected the Manifest to be created without errors.");
+ const CCNxName *copy = ccnxManifest_GetName(manifest);
+
+ assertTrue(ccnxName_Equals(name, copy), "Expected name to equal %s, got %s", ccnxName_ToString(name), ccnxName_ToString(copy));
+
+ ccnxName_Release(&name);
+ ccnxManifest_Release(&manifest);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_Manifest);
+ int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_ManifestHashGroup.c b/libccnx-common/ccnx/common/test/test_ccnx_ManifestHashGroup.c
new file mode 100644
index 00000000..c09fa63d
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_ManifestHashGroup.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../ccnx_ManifestHashGroup.c"
+
+#include <inttypes.h>
+#include <ccnx/common/ccnx_Manifest.h>
+
+#include <ccnx/common/ccnx_Name.h>
+#include <ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_PacketEncoder.h>
+#include <ccnx/common/codec/ccnxCodec_TlvPacket.h>
+#include <ccnx/common/ccnx_WireFormatMessage.h>
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/algol/parc_Object.h>
+#include <parc/algol/parc_ArrayList.h>
+
+#include <parc/testing/parc_ObjectTesting.h>
+
+LONGBOW_TEST_RUNNER(ccnx_ManifestHashGroup)
+{
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_ManifestHashGroup)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_ManifestHashGroup)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_AcquireRelease);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_Create);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_CreateFromJson);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_AppendGetPointer);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_PrependGetPointer);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_ToString);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_ToJson);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_IsFull);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_CreateInterestList_GroupLocator);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_CreateInterestList_OverrideLocator);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_CreateInterestList_NoLocator);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_Iterator);
+
+ // Metadata
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_BlockSize);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_DataSize);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_EntrySize);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_TreeHeight);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_Locator);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_OverallDataDigest);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxManifestHashGroup_HasMetadata);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_AcquireRelease)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ parcObjectTesting_AssertAcquireReleaseContract(ccnxManifestHashGroup_Acquire, group);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_Create)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_CreateFromJson)
+{
+ char *jsonString = "{ \"HashGroup\" : [ { \"type\" : 0, \"digest\" : \"FFFF\" } ] }";
+ PARCJSON *json = parcJSON_ParseString(jsonString);
+
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_CreateFromJson(json);
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ size_t actual = ccnxManifestHashGroup_GetNumberOfPointers(group);
+ size_t expected = 1;
+
+ assertTrue(actual == expected, "Expected %zu pointers, got %zu", expected, actual);
+
+ parcJSON_Release(&json);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_AppendGetPointer)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ PARCBuffer *buffer1 = parcBuffer_Allocate(32);
+ PARCBuffer *buffer2 = parcBuffer_Allocate(32);
+
+ ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, buffer1);
+ ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Manifest, buffer2);
+
+ size_t expected = 2;
+ size_t actual = ccnxManifestHashGroup_GetNumberOfPointers(group);
+
+ assertTrue(expected == actual, "Expected %zu, got %zu", expected, actual);
+ assertTrue(ccnxManifestHashGroupPointer_GetType(ccnxManifestHashGroup_GetPointerAtIndex(group, 0)) == CCNxManifestHashGroupPointerType_Data, "Expected data in the first slot");
+ assertTrue(ccnxManifestHashGroupPointer_GetType(ccnxManifestHashGroup_GetPointerAtIndex(group, 1)) == CCNxManifestHashGroupPointerType_Manifest, "Expected data in the first slot");
+
+ parcBuffer_Release(&buffer1);
+ parcBuffer_Release(&buffer2);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_PrependGetPointer)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ PARCBuffer *buffer1 = parcBuffer_Allocate(32);
+ PARCBuffer *buffer2 = parcBuffer_Allocate(32);
+
+ ccnxManifestHashGroup_PrependPointer(group, CCNxManifestHashGroupPointerType_Data, buffer1);
+ ccnxManifestHashGroup_PrependPointer(group, CCNxManifestHashGroupPointerType_Manifest, buffer2);
+
+ size_t expected = 2;
+ size_t actual = ccnxManifestHashGroup_GetNumberOfPointers(group);
+
+ assertTrue(expected == actual, "Expected %zu, got %zu", expected, actual);
+ assertTrue(ccnxManifestHashGroupPointer_GetType(ccnxManifestHashGroup_GetPointerAtIndex(group, 1)) == CCNxManifestHashGroupPointerType_Data, "Expected data in the first slot");
+ assertTrue(ccnxManifestHashGroupPointer_GetType(ccnxManifestHashGroup_GetPointerAtIndex(group, 0)) == CCNxManifestHashGroupPointerType_Manifest, "Expected data in the first slot");
+
+ parcBuffer_Release(&buffer1);
+ parcBuffer_Release(&buffer2);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+static CCNxManifestHashGroup *
+_createHashGroup(CCNxName *locator, size_t n, size_t blockSize, size_t dataSize, size_t entrySize, size_t treeHeight)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+
+ if (locator != NULL) {
+ ccnxManifestHashGroup_SetLocator(group, locator);
+ }
+
+ for (size_t i = 0; i < n; i++) {
+ PARCBuffer *buffer = parcBuffer_Allocate(32);
+ ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, buffer);
+ parcBuffer_Release(&buffer);
+ }
+
+ if (blockSize != 0) {
+ ccnxManifestHashGroup_SetBlockSize(group, blockSize);
+ }
+
+ if (dataSize != 0) {
+ ccnxManifestHashGroup_SetDataSize(group, dataSize);
+ }
+
+ if (entrySize != 0) {
+ ccnxManifestHashGroup_SetEntrySize(group, entrySize);
+ }
+
+ if (treeHeight != 0) {
+ ccnxManifestHashGroup_SetTreeHeight(group, treeHeight);
+ }
+
+ return group;
+}
+
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_Equals)
+{
+ CCNxName *locator = ccnxName_CreateFromCString("ccnx:/my/manifest");
+
+ CCNxManifestHashGroup *x = _createHashGroup(locator, 10, 0, 0, 0, 0);
+ CCNxManifestHashGroup *y = _createHashGroup(locator, 10, 0, 0, 0, 0);
+ CCNxManifestHashGroup *z = _createHashGroup(locator, 10, 0, 0, 0, 0);
+
+ CCNxManifestHashGroup *u1 = _createHashGroup(locator, 5, 0, 0, 0, 0);
+ CCNxManifestHashGroup *u2 = _createHashGroup(NULL, 10, 0, 0, 0, 0);
+ CCNxManifestHashGroup *u3 = _createHashGroup(locator, 10, 1, 0, 0, 0);
+ CCNxManifestHashGroup *u4 = _createHashGroup(locator, 10, 0, 1, 0, 0);
+ CCNxManifestHashGroup *u5 = _createHashGroup(locator, 10, 0, 0, 1, 0);
+ CCNxManifestHashGroup *u6 = _createHashGroup(locator, 10, 0, 0, 0, 1);
+
+ parcObjectTesting_AssertEqualsFunction(ccnxManifestHashGroup_Equals, x, y, z, u1, u2, u3, u4, u5, u6, NULL);
+
+ ccnxManifestHashGroup_Release(&x);
+ ccnxManifestHashGroup_Release(&y);
+ ccnxManifestHashGroup_Release(&z);
+
+ ccnxManifestHashGroup_Release(&u1);
+ ccnxManifestHashGroup_Release(&u2);
+ ccnxManifestHashGroup_Release(&u3);
+ ccnxManifestHashGroup_Release(&u4);
+ ccnxManifestHashGroup_Release(&u5);
+ ccnxManifestHashGroup_Release(&u6);
+
+ ccnxName_Release(&locator);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_ToString)
+{
+ char *jsonString = "{ \"HashGroup\" : [ { \"type\" : 0, \"digest\" : \"617364617364617364\" } ] }";
+ PARCJSON *json = parcJSON_ParseString(jsonString);
+
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_CreateFromJson(json);
+
+ char *stringForm = ccnxManifestHashGroup_ToString(group);
+ assertTrue(strcmp(jsonString, stringForm) == 0, "Expected %s and actual %s should be equal.", jsonString, stringForm);
+
+ parcMemory_Deallocate(&stringForm);
+ parcJSON_Release(&json);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_ToJson)
+{
+ char *jsonString = "{ \"HashGroup\" : [ { \"type\" : 0, \"digest\" : \"617364617364617364\" } ] }";
+ PARCJSON *json = parcJSON_ParseString(jsonString);
+
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_CreateFromJson(json);
+ PARCJSON *expected = ccnxManifestHashGroup_ToJson(group);
+
+ assertTrue(parcJSON_Equals(json, expected), "Expected the input and output JSON to be identical");
+
+ parcJSON_Release(&expected);
+ parcJSON_Release(&json);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_IsFull)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ for (size_t i = 0; i < MAX_NUMBER_OF_POINTERS; i++) {
+ PARCBuffer *buffer = parcBuffer_Allocate(32);
+ assertTrue(ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, buffer), "Expected the insertion to succeed");
+ parcBuffer_Release(&buffer);
+ }
+
+ PARCBuffer *buffer = parcBuffer_Allocate(32);
+ assertFalse(ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, buffer), "Expected the insertion to fail since the HashGroup is full.");
+ parcBuffer_Release(&buffer);
+
+ bool isFull = ccnxManifestHashGroup_IsFull(group);
+ assertTrue(isFull, "Expected the group to be full after %ul pointers", MAX_NUMBER_OF_POINTERS);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_CreateInterestList_OverrideLocator)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ PARCLinkedList *interestList = parcLinkedList_Create();
+ CCNxName *locator = ccnxName_CreateFromCString("ccnx:/locator");
+ for (size_t i = 0; i < MAX_NUMBER_OF_POINTERS; i++) {
+ PARCBuffer *buffer = parcBuffer_Allocate(32);
+ assertTrue(ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, buffer), "Expected the insertion to succeed");
+
+ CCNxInterest *interest = ccnxInterest_CreateSimple(locator);
+ ccnxInterest_SetContentObjectHashRestriction(interest, buffer);
+ parcLinkedList_Append(interestList, interest);
+
+ ccnxInterest_Release(&interest);
+ parcBuffer_Release(&buffer);
+ }
+
+ PARCLinkedList *extractedList = ccnxManifestHashGroup_CreateInterestList(group, locator);
+ assertTrue(parcLinkedList_Equals(interestList, extractedList), "Expected the interest lists to be equal");
+
+ parcLinkedList_Release(&interestList);
+ parcLinkedList_Release(&extractedList);
+ ccnxName_Release(&locator);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_CreateInterestList_GroupLocator)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ CCNxName *locator = ccnxName_CreateFromCString("ccnx:/group/locator");
+ ccnxManifestHashGroup_SetLocator(group, locator);
+
+ PARCLinkedList *interestList = parcLinkedList_Create();
+ for (size_t i = 0; i < MAX_NUMBER_OF_POINTERS; i++) {
+ PARCBuffer *buffer = parcBuffer_Allocate(32);
+ assertTrue(ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, buffer), "Expected the insertion to succeed");
+
+ CCNxInterest *interest = ccnxInterest_CreateSimple(locator);
+ ccnxInterest_SetContentObjectHashRestriction(interest, buffer);
+ parcLinkedList_Append(interestList, interest);
+
+ ccnxInterest_Release(&interest);
+ parcBuffer_Release(&buffer);
+ }
+
+ CCNxName *differentLocator = ccnxName_CreateFromCString("ccnx:/different/locator");
+ PARCLinkedList *extractedList = ccnxManifestHashGroup_CreateInterestList(group, differentLocator);
+ ccnxName_Release(&differentLocator);
+ assertTrue(parcLinkedList_Equals(interestList, extractedList), "Expected the interest lists to be equal");
+
+ parcLinkedList_Release(&interestList);
+ parcLinkedList_Release(&extractedList);
+ ccnxName_Release(&locator);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_CreateInterestList_NoLocator)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ for (size_t i = 0; i < MAX_NUMBER_OF_POINTERS; i++) {
+ PARCBuffer *buffer = parcBuffer_Allocate(32);
+ assertTrue(ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, buffer), "Expected the insertion to succeed");
+ parcBuffer_Release(&buffer);
+ }
+
+ PARCLinkedList *extractedList = ccnxManifestHashGroup_CreateInterestList(group, NULL);
+ assertTrue(parcLinkedList_Size(extractedList) == 0, "Expected the interest list to be empty since there was no valid locator");
+
+ parcLinkedList_Release(&extractedList);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_BlockSize)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ size_t blockSize = 10;
+ ccnxManifestHashGroup_SetBlockSize(group, blockSize);
+ size_t actual = ccnxManifestHashGroup_GetBlockSize(group);
+
+ assertTrue(blockSize == actual, "Expected %zu, got %zu", blockSize, actual);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_DataSize)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ size_t dataSize = 10;
+ ccnxManifestHashGroup_SetDataSize(group, dataSize);
+ size_t actual = ccnxManifestHashGroup_GetDataSize(group);
+
+ assertTrue(dataSize == actual, "Expected %zu, got %zu", dataSize, actual);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_EntrySize)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ size_t entrySize = 10;
+ ccnxManifestHashGroup_SetEntrySize(group, entrySize);
+ size_t actual = ccnxManifestHashGroup_GetEntrySize(group);
+
+ assertTrue(entrySize == actual, "Expected %zu, got %zu", entrySize, actual);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_TreeHeight)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ size_t treeHeight = 10;
+ ccnxManifestHashGroup_SetTreeHeight(group, treeHeight);
+ size_t actual = ccnxManifestHashGroup_GetTreeHeight(group);
+
+ assertTrue(treeHeight == actual, "Expected %zu, got %zu", treeHeight, actual);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_OverallDataDigest)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ PARCBuffer *digest = parcBuffer_Allocate(10);
+ ccnxManifestHashGroup_SetOverallDataDigest(group, digest);
+ const PARCBuffer *actual = ccnxManifestHashGroup_GetOverallDataDigest(group);
+
+ assertTrue(parcBuffer_Equals(digest, actual) == true, "Expected %s, got %s", parcBuffer_ToHexString(digest), parcBuffer_ToHexString(actual));
+
+ parcBuffer_Release(&digest);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_Locator)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ CCNxName *expected = ccnxName_CreateFromCString("ccnx:/flic/manifest");
+ ccnxManifestHashGroup_SetLocator(group, expected);
+ const CCNxName *actual = ccnxManifestHashGroup_GetLocator(group);
+
+ assertTrue(ccnxName_Equals(expected, actual) == true, "Expected %s, got %s", ccnxName_ToString(expected), ccnxName_ToString(actual));
+
+ ccnxName_Release(&expected);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_HasMetadata)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ assertFalse(ccnxManifestHashGroup_HasMetadata(group), "Expected an empty HashGroup to have no metadata");
+
+ CCNxName *expected = ccnxName_CreateFromCString("ccnx:/flic/manifest");
+ ccnxManifestHashGroup_SetLocator(group, expected);
+
+ assertTrue(ccnxManifestHashGroup_HasMetadata(group), "Expected a HashGroup with a locator to have metadata");
+
+ ccnxName_Release(&expected);
+ ccnxManifestHashGroup_Release(&group);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxManifestHashGroup_Iterator)
+{
+ CCNxManifestHashGroup *group = ccnxManifestHashGroup_Create();
+ assertNotNull(group, "Expected non-null CCNxManifestHashGroup");
+
+ for (size_t i = 0; i < MAX_NUMBER_OF_POINTERS; i++) {
+ PARCBuffer *buffer = parcBuffer_Allocate(10);
+ parcBuffer_Flip(parcBuffer_PutUint32(buffer, i));
+ assertTrue(ccnxManifestHashGroup_AppendPointer(group, CCNxManifestHashGroupPointerType_Data, buffer), "Expected the insertion to succeed");
+ parcBuffer_Release(&buffer);
+ }
+
+ PARCIterator *itr = ccnxManifestHashGroup_Iterator(group);
+
+ size_t i = 0;
+ while (parcIterator_HasNext(itr)) {
+ CCNxManifestHashGroupPointer *ptr = (CCNxManifestHashGroupPointer *) parcIterator_Next(itr);
+ const PARCBuffer *digest = ccnxManifestHashGroupPointer_GetDigest(ptr);
+ size_t index = parcBuffer_GetUint32((PARCBuffer *) digest);
+ assertTrue(index == i, "Expected the right digest pointer to be extracted, got %zu, expected %zu", index, i);
+ i++;
+ }
+
+ parcIterator_Release(&itr);
+
+ bool isFull = ccnxManifestHashGroup_IsFull(group);
+ assertTrue(isFull, "Expected the group to be full after %ul pointers", MAX_NUMBER_OF_POINTERS);
+
+ ccnxManifestHashGroup_Release(&group);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_ManifestHashGroup);
+ int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_Name.c b/libccnx-common/ccnx/common/test/test_ccnx_Name.c
new file mode 100644
index 00000000..2adec939
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_Name.c
@@ -0,0 +1,735 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+
+#include "../ccnx_Name.c"
+
+#include <LongBow/unit-test.h>
+
+#include <stdio.h>
+#include <limits.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(ccnx_Name)
+{
+ LONGBOW_RUN_TEST_FIXTURE(Local);
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Specialization);
+ LONGBOW_RUN_TEST_FIXTURE(Performance);
+}
+
+LONGBOW_TEST_RUNNER_SETUP(ccnx_Name)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_Name)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_CreateFromCString);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_CreateFromCString_Root);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_CreateFromCString_BadScheme);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_CreateFromCString_NoScheme);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_CreateFromCString_ZeroComponents);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_CreateFromBuffer);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_IsValid_True);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_IsValid_False);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_HashCode);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_LeftMostHashCode);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_HashCode_LeftMostHashCode);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_ToString);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_ToString_Root);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_ToString_NoPath);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_ToString_LCI);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_Copy_Zero);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_Copy_NonZero);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_CreateAndDestroy);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_Trim);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_Trim_MAXINT);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_StartsWith_True);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_StartsWith_FalseShorterPrefix);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_StartsWith_FalseLongerPrefix);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_Compare);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxName_ComposeNAME);
+
+ LONGBOW_RUN_TEST_CASE(Global, ParseTest1);
+ LONGBOW_RUN_TEST_CASE(Global, ParseTest2);
+
+ LONGBOW_RUN_TEST_CASE(Global, MemoryProblem);
+}
+
+static size_t _longBowGlobal_Global_outstanding;
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ _longBowGlobal_Global_outstanding = parcMemory_Outstanding();
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ LongBowStatus result = LONGBOW_STATUS_SUCCEEDED;
+
+ size_t allocationsLeaked = parcMemory_Outstanding() - _longBowGlobal_Global_outstanding;
+
+ if (allocationsLeaked > 0) {
+ printf("%s leaks memory by %zd allocations\n", longBowTestCase_GetName(testCase), allocationsLeaked);
+ parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ result = LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return result;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_ComposeNAME)
+{
+ char *string = "lci:/a/b/c";
+
+ CCNxName *basename = ccnxName_CreateFromCString("lci:/a/b");
+ CCNxName *expected = ccnxName_CreateFromCString(string);
+
+ CCNxName *actual = ccnxName_ComposeNAME(basename, "c");
+ assertTrue(ccnxName_Equals(expected, actual), "Failed.");
+
+ ccnxName_Release(&basename);
+ ccnxName_Release(&expected);
+ ccnxName_Release(&actual);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_IsValid_True)
+{
+ char *string = "lci:/a/b/c";
+ CCNxName *name = ccnxName_CreateFromCString(string);
+ assertTrue(ccnxName_IsValid(name), "Expected %s to be a valid CCNxName.", string);
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_IsValid_False)
+{
+ assertFalse(ccnxName_IsValid(NULL), "Expected NULL to be an invalid CCNxName.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_Equals)
+{
+ CCNxName *x = ccnxName_CreateFromCString("lci:/a/b/c");
+ CCNxName *y = ccnxName_CreateFromCString("lci:/a/b/c");
+ CCNxName *z = ccnxName_CreateFromCString("lci:/a/b/c");
+ CCNxName *u1 = ccnxName_CreateFromCString("lci:/a/b");
+ CCNxName *u2 = ccnxName_CreateFromCString("lci:/a/b/d");
+
+ assertEqualsContract(ccnxName_Equals, x, y, z, u1, u2);
+
+ ccnxName_Release(&x);
+ ccnxName_Release(&y);
+ ccnxName_Release(&z);
+ ccnxName_Release(&u1);
+ ccnxName_Release(&u2);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_ToString_Root)
+{
+ const char *expected = "ccnx:/";
+
+ CCNxName *name = ccnxName_CreateFromCString(expected);
+
+ char *actual = ccnxName_ToString(name);
+
+ assertTrue(strcmp(expected, actual) == 0, "Expected '%s' actual '%s'", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxName_Release(&name);
+
+ name = ccnxName_CreateFromCString("ccnx:");
+ actual = ccnxName_ToString(name);
+
+ assertTrue(strcmp(expected, actual) == 0, "Expected '%s' actual '%s'", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_ToString_NoPath)
+{
+ const char *expected = "ccnx:/";
+
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:");
+
+ char *actual = ccnxName_ToString(name);
+
+ assertTrue(strcmp(expected, actual) == 0, "Expected '%s' actual '%s'", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_Trim)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/a/b/c");
+
+ ccnxName_Trim(name, 1);
+
+ const char *expected = "ccnx:/a/b";
+ char *actual = ccnxName_ToString(name);
+
+ assertTrue(strcmp(expected, actual) == 0, "Expected '%s' actual '%s'", expected, actual);
+
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_Trim_MAXINT)
+{
+ CCNxName *name = ccnxName_CreateFromCString("ccnx:/a/b/c");
+
+ ccnxName_Trim(name, INT_MAX);
+
+ const char *expected = "ccnx:/";
+ char *actual = ccnxName_ToString(name);
+
+ assertTrue(strcmp(expected, actual) == 0, "Expected '%s' actual '%s'", expected, actual);
+
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_Copy_Zero)
+{
+ const char *uri = "ccnx:/"; // A Name with 1 zero-length segment
+
+ CCNxName *name = ccnxName_CreateFromCString(uri);
+
+ CCNxName *copy = ccnxName_Copy(name);
+ assertNotNull(copy, "Expect non-null result.");
+
+ char *expected = ccnxName_ToString(name);
+ char *actual = ccnxName_ToString(copy);
+
+ assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual);
+
+ ccnxName_Release(&name);
+ ccnxName_Release(&copy);
+ parcMemory_Deallocate((void **) &expected);
+ parcMemory_Deallocate((void **) &actual);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_Copy_NonZero)
+{
+ const char *uri = "ccnx:/a/b/c/d/e";
+
+ CCNxName *name = ccnxName_CreateFromCString(uri);
+
+ CCNxName *copy = ccnxName_Copy(name);
+ assertNotNull(copy, "Expect non-null result.");
+
+ char *expected = ccnxName_ToString(name);
+ char *actual = ccnxName_ToString(copy);
+
+ assertTrue(strcmp(expected, actual) == 0, "Expected '%s', actual '%s'", expected, actual);
+
+ ccnxName_Release(&name);
+ ccnxName_Release(&copy);
+ parcMemory_Deallocate((void **) &expected);
+ parcMemory_Deallocate((void **) &actual);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_HashCode)
+{
+ const char *uriA = "lci:/a/b/c/d/e/";
+ const char *uriB = "lci:/a/b/c/d/e/";
+
+ CCNxName *nameA = ccnxName_CreateFromCString(uriA);
+ CCNxName *nameB = ccnxName_CreateFromCString(uriB);
+
+ PARCHashCode codeA = ccnxName_HashCode(nameA);
+ PARCHashCode codeB = ccnxName_HashCode(nameB);
+
+ // We know the hashcode of uriA is not zero
+ assertTrue(codeA != 0, "Expected a non-zero hash code");
+
+ assertTrue(codeA == codeB, "Expected %" PRIPARCHashCode " == %" PRIPARCHashCode, codeA, codeB);
+
+ ccnxName_Release(&nameA);
+ ccnxName_Release(&nameB);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_HashCode_LeftMostHashCode)
+{
+ const char *uriA = "lci:/a/b/c/d/e/";
+ const char *uriB = "lci:/a/b/c/d/e/";
+
+ CCNxName *nameA = ccnxName_CreateFromCString(uriA);
+ CCNxName *nameB = ccnxName_CreateFromCString(uriB);
+
+ PARCHashCode codeA = ccnxName_HashCode(nameA);
+ PARCHashCode codeB = ccnxName_HashCode(nameB);
+ PARCHashCode leftMostCodeA = ccnxName_LeftMostHashCode(nameA, INT_MAX);
+ PARCHashCode leftMostCodeB = ccnxName_LeftMostHashCode(nameB, INT_MAX);
+
+ // We know the hashcode of uriA is not zero
+ assertTrue(codeA != 0, "Expected a non-zero hash code");
+
+ assertTrue(codeA == codeB, "Expected %" PRIPARCHashCode " == %" PRIPARCHashCode, codeA, codeB);
+ assertTrue(codeA == leftMostCodeA, "Expected %" PRIPARCHashCode " == %" PRIPARCHashCode, codeA, leftMostCodeA);
+ assertTrue(codeA == leftMostCodeB, "Expected %" PRIPARCHashCode " == %" PRIPARCHashCode, codeA, leftMostCodeB);
+
+ ccnxName_Release(&nameA);
+ ccnxName_Release(&nameB);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_LeftMostHashCode)
+{
+ const char *uriA = "lci:/a/b/c/d/e/";
+ const char *uriB = "lci:/a/b/c/d/e/";
+
+ CCNxName *nameA = ccnxName_CreateFromCString(uriA);
+ CCNxName *nameB = ccnxName_CreateFromCString(uriB);
+
+ PARCHashCode codeA = ccnxName_LeftMostHashCode(nameA, 2);
+ PARCHashCode codeB = ccnxName_LeftMostHashCode(nameB, 2);
+
+ assertTrue(codeA == codeB, "Expected %" PRIPARCHashCode " == %" PRIPARCHashCode, codeA, codeB);
+
+ ccnxName_Release(&nameA);
+ ccnxName_Release(&nameB);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_CreateAndDestroy)
+{
+ CCNxName *name = ccnxName_Create();
+ assertNotNull(name, "Expected non-null");
+ ccnxName_Release(&name);
+ assertNull(name, "Expected null");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_CreateFromCString)
+{
+ const char *uri = "lci:/CCN-Python-Test";
+
+ CCNxName *name = ccnxName_CreateFromCString(uri);
+ ccnxName_Display(name, 0);
+ assertNotNull(name, "Expected non-null");
+
+ size_t expected = 1;
+ size_t actual = ccnxName_GetSegmentCount(name);
+
+ assertTrue(expected == actual, "Expected %zd segments, actual %zd", expected, actual);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_CreateFromCString_BadScheme)
+{
+ const char *uri = "abcd:/CCN-Python-Test/Echo";
+
+ CCNxName *name = ccnxName_CreateFromCString(uri);
+ assertNull(name, "Expected null");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_CreateFromCString_NoScheme)
+{
+ const char *uri = "/paravion";
+
+ CCNxName *name = ccnxName_CreateFromCString(uri);
+ assertNull(name, "Expected null");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_CreateFromCString_ZeroComponents)
+{
+ const char *uri = "lci:";
+
+ CCNxName *name = ccnxName_CreateFromCString(uri);
+ assertNotNull(name, "Expected non-null result from ccnxName_CreateFromCString");
+
+ size_t expected = 0;
+ size_t actual = ccnxName_GetSegmentCount(name);
+
+ assertTrue(expected == actual, "Expected %zd segments, actual %zd", expected, actual);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_CreateFromCString_Root)
+{
+ const char *uri = "lci:/";
+
+ CCNxName *name = ccnxName_CreateFromCString(uri);
+ assertNotNull(name, "Expected non-null");
+
+ size_t expected = 1;
+ size_t actual = ccnxName_GetSegmentCount(name);
+
+ assertTrue(expected == actual, "Expected %zd segments, actual %zd", expected, actual);
+
+ CCNxNameSegment *segment = ccnxName_GetSegment(name, 0);
+
+ size_t segmentLength = ccnxNameSegment_Length(segment);
+ assertTrue(segmentLength == 0, "Expected a zero length segment, actual %zd", segmentLength);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_CreateFromBuffer)
+{
+ PARCBuffer *buffer = parcBuffer_WrapCString("lci:/CCN-Python-Test");
+ CCNxName *name = ccnxName_CreateFromBuffer(buffer);
+ assertNotNull(name, "Expected non-null");
+
+ size_t expected = 1;
+ size_t actual = ccnxName_GetSegmentCount(name);
+
+ assertTrue(expected == actual, "Expected %zd segments, actual %zd", expected, actual);
+
+ ccnxName_Release(&name);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_ToString_LCI)
+{
+ const char *lci = "lci:/a/b";
+ const char *expectedURI = "ccnx:/a/b";
+
+ CCNxName *name = ccnxName_CreateFromCString(lci);
+
+ size_t expected = 2;
+ size_t actual = ccnxName_GetSegmentCount(name);
+
+ assertTrue(expected == actual,
+ "Expected %zd segments, actual %zd", expected, actual);
+
+ char *string = ccnxName_ToString(name);
+ assertTrue(strcmp(expectedURI, string) == 0,
+ "Expected '%s' actual '%s'", expectedURI, string);
+ parcMemory_Deallocate((void **) &string);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_ToString)
+{
+ const char *uri = "ccnx:/a/b";
+
+ CCNxName *name = ccnxName_CreateFromCString(uri);
+
+ size_t expected = 2;
+ size_t actual = ccnxName_GetSegmentCount(name);
+
+ assertTrue(expected == actual,
+ "Expected %zd segments, actual %zd", expected, actual);
+
+ char *string = ccnxName_ToString(name);
+ assertTrue(strcmp(uri, string) == 0,
+ "Expected '%s' actual '%s'", uri, string);
+ parcMemory_Deallocate((void **) &string);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_Compare)
+{
+ CCNxName *value = ccnxName_CreateFromCString("lci:/a/b/c");
+ CCNxName *equal1 = ccnxName_CreateFromCString("lci:/a/b/c");
+
+ CCNxName **equivalents = (CCNxName *[]) {
+ equal1,
+ NULL
+ };
+
+ CCNxName *lesser1 = ccnxName_CreateFromCString("lci:/a/b");
+ CCNxName *lesser2 = ccnxName_CreateFromCString("lci:/a/b/b");
+ CCNxName **lesser = (CCNxName *[]) {
+ lesser1,
+ lesser2,
+ NULL
+ };
+
+ CCNxName *greater1 = ccnxName_CreateFromCString("lci:/a/b/d");
+ CCNxName *greater2 = ccnxName_CreateFromCString("lci:/a/b/c/d");
+ CCNxName **greater = (CCNxName *[]) {
+ greater1,
+ greater2,
+ NULL
+ };
+
+ assertCompareToContract(ccnxName_Compare, value, equivalents, lesser, greater);
+
+ for (int i = 0; lesser[i] != NULL; i++) {
+ ccnxName_Release(&lesser[i]);
+ }
+ for (int i = 0; greater[i] != NULL; i++) {
+ ccnxName_Release(&greater[i]);
+ }
+ for (int i = 0; equivalents[i] != NULL; i++) {
+ ccnxName_Release(&equivalents[i]);
+ }
+ ccnxName_Release(&value);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_StartsWith_True)
+{
+ const char *uriA = "lci:/a/b/c/d/e/";
+ const char *uriB = "lci:/a/b/c/d/e/";
+
+ CCNxName *nameA = ccnxName_CreateFromCString(uriA);
+ CCNxName *nameB = ccnxName_CreateFromCString(uriB);
+
+ bool actual = ccnxName_StartsWith(nameA, nameA);
+
+ assertTrue(actual, "Expected true");
+
+ ccnxName_Release(&nameA);
+ ccnxName_Release(&nameB);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_StartsWith_FalseShorterPrefix)
+{
+ const char *uriA = "lci:/a/b/c/d/e";
+ const char *prefix = "lci:/a/b/d";
+
+ CCNxName *nameA = ccnxName_CreateFromCString(uriA);
+ CCNxName *nameB = ccnxName_CreateFromCString(prefix);
+
+ bool actual = ccnxName_StartsWith(nameA, nameB);
+
+ assertFalse(actual, "Expected false");
+
+ ccnxName_Release(&nameA);
+ ccnxName_Release(&nameB);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxName_StartsWith_FalseLongerPrefix)
+{
+ const char *uriA = "lci:/a/b/c/d/e";
+ const char *prefix = "lci:/a/b/c/d/e/f";
+
+ CCNxName *nameA = ccnxName_CreateFromCString(uriA);
+ CCNxName *nameB = ccnxName_CreateFromCString(prefix);
+
+ bool actual = ccnxName_StartsWith(nameA, nameB);
+
+ assertFalse(actual, "Expected false");
+
+ ccnxName_Release(&nameA);
+ ccnxName_Release(&nameB);
+}
+
+static CCNxNameSegment *
+createSegment(PARCBuffer *buffer, size_t start, size_t end)
+{
+ parcBuffer_SetPosition(buffer, start);
+ PARCBuffer *slice = parcBuffer_Slice(buffer);
+ parcBuffer_SetLimit(slice, end);
+
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, slice);
+ parcBuffer_Release(&slice);
+
+ return segment;
+}
+
+LONGBOW_TEST_CASE(Global, MemoryProblem)
+{
+ char memory[] = "abcdefghijklmnopqrstuvwxyz";
+ PARCBuffer *buffer = parcBuffer_Wrap(memory, sizeof(memory), 0, sizeof(memory));
+
+ CCNxName *name = ccnxName_Create();
+
+ CCNxNameSegment *segment1 = createSegment(buffer, 2, 4); // "cd"
+ ccnxName_Append(name, segment1);
+
+ CCNxNameSegment *segment2 = createSegment(buffer, 10, 14); // "klmn"
+ ccnxName_Append(name, segment2);
+
+ CCNxName *name2 = ccnxName_Acquire(name);
+
+ parcBuffer_Release(&buffer);
+ ccnxName_Release(&name2);
+
+ ccnxName_Release(&name);
+ ccnxNameSegment_Release(&segment1);
+ ccnxNameSegment_Release(&segment2);
+}
+
+LONGBOW_TEST_CASE(Global, ParseTest1)
+{
+ CCNxName *name = ccnxName_CreateFromCString("lci:/" CCNxNameLabel_Name "=foot/3=toe/4=nail");
+ assertNotNull(name, "Expected non-null value from ccnxName_CreateFromCString");
+
+ ccnxName_Display(name, 0);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_CASE(Global, ParseTest2)
+{
+ CCNxName *a = ccnxName_CreateFromCString("lci:/a/b/c");
+ CCNxName *b = ccnxName_CreateFromCString("lci:/Name=a/Name=b/Name=c");
+ assertTrue(ccnxName_Equals(a, b), "Expected to be equal");
+ ccnxName_Release(&a);
+ ccnxName_Release(&b);
+
+ char *expected = "ccnx:/test/Name=MiISAg%3D%3D";
+ CCNxName *name = ccnxName_CreateFromCString(expected);
+ assertNotNull(name, "Expected non-null value from ccnxName_CreateFromCString");
+ char *actual = ccnxName_ToString(name);
+ printf("%s\n", actual);
+ assertTrue(strcmp(expected, actual) == 0, "Expected '%s' actual '%s'", expected, actual);
+ parcMemory_Deallocate(&actual);
+
+ ccnxName_Display(name, 0);
+
+ ccnxName_Release(&name);
+}
+
+LONGBOW_TEST_FIXTURE(Local)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Local)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Local)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Specialization)
+{
+ LONGBOW_RUN_TEST_CASE(Specialization, ccnxName_Prefix);
+ LONGBOW_RUN_TEST_CASE(Specialization, ccnxName_Prefix_Excess);
+ LONGBOW_RUN_TEST_CASE(Specialization, ccnxName_Prefix_0);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Specialization)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Specialization)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Specialization, ccnxName_Prefix)
+{
+ CCNxName *a = ccnxName_CreateFromCString("ccnx:/a/b/c");
+ CCNxName *expected = ccnxName_CreateFromCString("ccnx:/a");
+
+ CCNxName *actual = ccnxName_CreatePrefix(a, 1);
+
+ assertTrue(ccnxName_Equals(expected, actual), "Mismatched results.");
+
+ ccnxName_Release(&a);
+ ccnxName_Release(&expected);
+ ccnxName_Release(&actual);
+}
+
+LONGBOW_TEST_CASE(Specialization, ccnxName_Prefix_Excess)
+{
+ CCNxName *a = ccnxName_CreateFromCString("ccnx:/a/b/c");
+ CCNxName *expected = ccnxName_CreateFromCString("ccnx:/a/b/c");
+
+ CCNxName *actual = ccnxName_CreatePrefix(a, 100);
+
+ assertTrue(ccnxName_Equals(expected, actual), "Mismatched results.");
+
+ ccnxName_Release(&a);
+ ccnxName_Release(&expected);
+ ccnxName_Release(&actual);
+}
+
+LONGBOW_TEST_CASE(Specialization, ccnxName_Prefix_0)
+{
+ CCNxName *a = ccnxName_CreateFromCString("ccnx:/a/b/c");
+ CCNxName *expected = ccnxName_CreateFromCString("ccnx:");
+
+ CCNxName *actual = ccnxName_CreatePrefix(a, 0);
+
+ assertTrue(ccnxName_Equals(expected, actual), "Mismatched results.");
+
+ ccnxName_Release(&a);
+ ccnxName_Release(&expected);
+ ccnxName_Release(&actual);
+}
+
+LONGBOW_TEST_FIXTURE_OPTIONS(Performance, .enabled = false)
+{
+ LONGBOW_RUN_TEST_CASE(Performance, ccnxName_Create);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Performance)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Performance)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Performance, ccnxName_Create)
+{
+ PARCBuffer *value = parcBuffer_WrapCString("Hello");
+
+ for (int i = 0; i < 10000; i++) {
+ CCNxName *name = ccnxName_Create();
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, value);
+ for (int j = 0; j < 1000; j++) {
+ ccnxName_Append(name, segment);
+ }
+ ccnxNameSegment_Release(&segment);
+ ccnxName_Release(&name);
+ }
+ parcBuffer_Release(&value);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_Name);
+ int exitStatus = longBowMain(argc, argv, testRunner);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_NameLabel.c b/libccnx-common/ccnx/common/test/test_ccnx_NameLabel.c
new file mode 100755
index 00000000..428c2f29
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_NameLabel.c
@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+#include "../ccnx_NameLabel.c"
+
+#include <LongBow/unit-test.h>
+#include <stdio.h>
+#include <parc/algol/parc_SafeMemory.h>
+#include <parc/testing/parc_ObjectTesting.h>
+
+
+LONGBOW_TEST_RUNNER(ccnx_NameType)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Errors);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_NameType)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_NameType)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameLabel_Create);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameLabel_AcquireRelease);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameLabel_GetType);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameLabel_GetParameter);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameLabel_Equals);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameLabel_Copy);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic_NULL);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic_Empty);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic_App0);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic_App);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Resolve_Numeric_Decimal);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Resolve_Numeric_Hex);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Resolve_Unknown_Mnemonic);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_BuildString_KnownLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_BuildString_UnknownLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_BuildString_AppLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_BuildString_AppLabel4096);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse_DefaultLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse_EmptyLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse_KnownLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse_DecimalParameterLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse_HexadecimalParameterLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse_OutOfRangeLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse_BadHexLabel);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameType_Parse_UknownMnemonicLabel);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic)
+{
+ char *mnemonic = "Name";
+ PARCBuffer *label = parcBuffer_WrapCString(mnemonic);
+ CCNxNameLabelType actual = _ccnxNameLabelType_Resolve(label);
+ assertTrue(actual == CCNxNameLabelType_NAME,
+ "Expected an CCNxNameType_NAME type for the mnemonic '%s'", mnemonic);
+ parcBuffer_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic_NULL)
+{
+ CCNxNameLabelType actual = _ccnxNameLabelType_Resolve(NULL);
+ assertTrue(actual == CCNxNameLabelType_NAME,
+ "Expected an CCNxNameType_NAME type for a NULL mnemonic.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic_Empty)
+{
+ PARCBuffer *label = parcBuffer_Allocate(0);
+ CCNxNameLabelType actual = _ccnxNameLabelType_Resolve(label);
+ assertTrue(actual == CCNxNameLabelType_NAME,
+ "Expected an CCNxNameType_NAME type for an empty mnemonic.");
+ parcBuffer_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic_App0)
+{
+ PARCBuffer *label = parcBuffer_WrapCString("app");
+ CCNxNameLabelType actual = _ccnxNameLabelType_Resolve(label);
+ assertTrue(actual == CCNxNameLabelType_App(0),
+ "Expected 0x%04x type, actual 0x%04x", CCNxNameLabelType_App(0), actual);
+ parcBuffer_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Resolve_Mnemonic_App)
+{
+ PARCBuffer *label = parcBuffer_WrapCString("app");
+ CCNxNameLabelType actual = _ccnxNameLabelType_Resolve(label);
+ assertTrue(actual == CCNxNameLabelType_App(0),
+ "Expected 0x%04x type, actual 0x%04x", CCNxNameLabelType_App(0), actual);
+ parcBuffer_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Resolve_Numeric_Decimal)
+{
+ PARCBuffer *label = parcBuffer_WrapCString("16");
+ CCNxNameLabelType actual = _ccnxNameLabelType_Resolve(label);
+ assertTrue(actual == CCNxNameLabelType_CHUNK,
+ "Expected type %d, actual %d", CCNxNameLabelType_CHUNK, actual);
+ parcBuffer_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Resolve_Numeric_Hex)
+{
+ CCNxNameLabelType expected = 0xF000;
+ PARCBuffer *label = parcBuffer_WrapCString("0xF000");
+ CCNxNameLabelType actual = _ccnxNameLabelType_Resolve(label);
+ assertTrue(actual == expected,
+ "Expected type %d, actual %d", expected, actual);
+ parcBuffer_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Resolve_Unknown_Mnemonic)
+{
+ CCNxNameLabelType expected = CCNxNameLabelType_Unknown;
+ PARCBuffer *label = parcBuffer_WrapCString("xyzzy");
+ CCNxNameLabelType actual = _ccnxNameLabelType_Resolve(label);
+ assertTrue(actual == expected,
+ "Expected type %d, actual %d", expected, actual);
+ parcBuffer_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_BuildString_KnownLabel)
+{
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+
+ CCNxNameLabel *label = ccnxNameLabel_Create(CCNxNameLabelType_CHUNK, NULL);
+ ccnxNameLabel_BuildString(label, composer);
+ ccnxNameLabel_Release(&label);
+
+ PARCBuffer *expected = parcBuffer_WrapCString(CCNxNameLabel_Chunk "=");
+ PARCBuffer *actual = parcBuffer_Flip(parcBufferComposer_GetBuffer(composer));
+
+ assertTrue(parcBuffer_Equals(expected, actual),
+ "Expected a successful label lookup.");
+ parcBuffer_Release(&expected);
+ parcBufferComposer_Release(&composer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_BuildString_UnknownLabel)
+{
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ CCNxNameLabel *label = ccnxNameLabel_Create(1111, NULL);
+ ccnxNameLabel_BuildString(label, composer);
+ ccnxNameLabel_Release(&label);
+
+ PARCBuffer *expected = parcBuffer_WrapCString("1111" "=");
+ PARCBuffer *actual = parcBuffer_Flip(parcBufferComposer_GetBuffer(composer));
+
+ assertTrue(parcBuffer_Equals(expected, actual),
+ "Expected a successful label lookup.");
+
+ parcBuffer_Release(&expected);
+ parcBufferComposer_Release(&composer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_BuildString_AppLabel)
+{
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+
+ PARCBuffer *parameter = parcBuffer_WrapCString("0");
+ CCNxNameLabel *label = ccnxNameLabel_Create(CCNxNameLabelType_App(0), parameter);
+ ccnxNameLabel_BuildString(label, composer);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&parameter);
+
+ PARCBuffer *expected = parcBuffer_WrapCString("App:0" "=");
+ PARCBuffer *actual = parcBuffer_Flip(parcBufferComposer_GetBuffer(composer));
+
+ assertTrue(parcBuffer_Equals(expected, actual),
+ "Expected a successful label lookup.");
+
+ parcBuffer_Release(&expected);
+ parcBufferComposer_Release(&composer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_BuildString_AppLabel4096)
+{
+ PARCBufferComposer *composer = parcBufferComposer_Create();
+ PARCBuffer *parameter = parcBuffer_WrapCString("4096");
+ CCNxNameLabel *label = ccnxNameLabel_Create(CCNxNameLabelType_App(4096), parameter);
+ ccnxNameLabel_BuildString(label, composer);
+
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&parameter);
+
+ PARCBuffer *expected = parcBuffer_WrapCString("App:4096" "=");
+ PARCBuffer *actual = parcBuffer_Flip(parcBufferComposer_GetBuffer(composer));
+
+ assertTrue(parcBuffer_Equals(expected, actual),
+ "Expected a successful label lookup.");
+
+ parcBuffer_Release(&expected);
+ parcBufferComposer_Release(&composer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameLabel_GetType)
+{
+ CCNxNameLabelType type = CCNxNameLabelType_NAME;
+ PARCBuffer *parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *label = ccnxNameLabel_Create(type, parameter);
+
+ CCNxNameLabelType actual = ccnxNameLabel_GetType(label);
+
+ assertTrue(type == actual, "Expected type %u, actual %u", type, actual);
+
+ parcBuffer_Release(&parameter);
+ ccnxNameLabel_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameLabel_GetParameter)
+{
+ CCNxNameLabelType type = CCNxNameLabelType_NAME;
+ PARCBuffer *parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *label = ccnxNameLabel_Create(type, parameter);
+ PARCBuffer *actual = ccnxNameLabel_GetParameter(label);
+
+ assertTrue(parcBuffer_Equals(parameter, actual), "Expected parameter to be equal to the initial parameter.");
+ parcBuffer_Release(&parameter);
+ ccnxNameLabel_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameLabel_Create)
+{
+ CCNxNameLabelType type = CCNxNameLabelType_NAME;
+ PARCBuffer *parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *label = ccnxNameLabel_Create(type, parameter);
+ parcBuffer_Release(&parameter);
+ ccnxNameLabel_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameLabel_Copy)
+{
+ PARCBuffer *parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *label = ccnxNameLabel_Create(CCNxNameLabelType_NAME, parameter);
+ parcBuffer_Release(&parameter);
+
+ CCNxNameLabel *copy = ccnxNameLabel_Copy(label);
+
+ assertTrue(ccnxNameLabel_Equals(label, copy), "Expected copy to the equal to the original.");
+
+ assertTrue(label != copy, "Expected a copy to be distinct from the original.");
+ ccnxNameLabel_Release(&label);
+ ccnxNameLabel_Release(&copy);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameLabel_Equals)
+{
+ PARCBuffer *parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *x = ccnxNameLabel_Create(CCNxNameLabelType_SERIAL, parameter);
+ parcBuffer_Release(&parameter);
+
+ parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *y = ccnxNameLabel_Create(CCNxNameLabelType_SERIAL, parameter);
+ parcBuffer_Release(&parameter);
+
+ parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *z = ccnxNameLabel_Create(CCNxNameLabelType_SERIAL, parameter);
+ parcBuffer_Release(&parameter);
+
+ parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *u1 = ccnxNameLabel_Create(CCNxNameLabelType_CHUNK, parameter);
+ parcBuffer_Release(&parameter);
+
+ parameter = parcBuffer_WrapCString("Goodbye");
+ CCNxNameLabel *u2 = ccnxNameLabel_Create(CCNxNameLabelType_SERIAL, parameter);
+ parcBuffer_Release(&parameter);
+
+ assertEqualsContract(ccnxNameLabel_Equals, x, y, z, u1, u2, NULL);
+
+ ccnxNameLabel_Release(&x);
+ ccnxNameLabel_Release(&y);
+ ccnxNameLabel_Release(&z);
+ ccnxNameLabel_Release(&u1);
+ ccnxNameLabel_Release(&u2);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameLabel_AcquireRelease)
+{
+ CCNxNameLabelType type = CCNxNameLabelType_NAME;
+ PARCBuffer *parameter = parcBuffer_WrapCString("Hello");
+ CCNxNameLabel *label = ccnxNameLabel_Create(type, parameter);
+
+ parcObjectTesting_AssertAcquireReleaseContract(ccnxNameLabel_Acquire, label);
+
+ parcBuffer_Release(&parameter);
+ ccnxNameLabel_Release(&label);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse)
+{
+ char *expected = "App:1=value";
+ PARCBuffer *buffer = parcBuffer_WrapCString(expected);
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+ char *actual = ccnxNameLabel_ToString(label);
+ assertTrue(parcBuffer_Position(buffer) == 6, "Expected position to be 6, actual %zd", parcBuffer_Position(buffer));
+ assertTrue(strcmp("App:1=", actual) == 0, "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&buffer);
+
+ expected = "10:param=value";
+ buffer = parcBuffer_WrapCString(expected);
+ label = ccnxNameLabel_Parse(buffer);
+ actual = ccnxNameLabel_ToString(label);
+ assertTrue(parcBuffer_Position(buffer) == 9, "Expected position to be 9, actual %zd", parcBuffer_Position(buffer));
+ assertTrue(strcmp("10:param=", actual) == 0, "Expected %s, actual %s", "10:param=", actual);
+ parcMemory_Deallocate((void **) &actual);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse_DecimalParameterLabel)
+{
+ char *expected = "10:param=value";
+ PARCBuffer *buffer = parcBuffer_WrapCString(expected);
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+ char *actual = ccnxNameLabel_ToString(label);
+ assertTrue(parcBuffer_Position(buffer) == 9, "Expected position to be 9, actual %zd", parcBuffer_Position(buffer));
+ assertTrue(strcmp("10:param=", actual) == 0, "Expected %s, actual %s", "10:param=", actual);
+ parcMemory_Deallocate((void **) &actual);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse_HexadecimalParameterLabel)
+{
+ PARCBuffer *buffer = parcBuffer_WrapCString("0xaa:param=value");
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+ char *actual = ccnxNameLabel_ToString(label);
+ assertTrue(parcBuffer_Position(buffer) == 11, "Expected position to be 11, actual %zd", parcBuffer_Position(buffer));
+ char *expected = "170:param=";
+ assertTrue(strcmp(expected, actual) == 0, "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse_BadHexLabel)
+{
+ PARCBuffer *buffer = parcBuffer_WrapCString("0xgg:param=value");
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+ assertFalse(ccnxNameLabel_IsValid(label), "Expected an invalid CCNxNameLabel from an invalid specification.");
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse_OutOfRangeLabel)
+{
+ PARCBuffer *buffer = parcBuffer_WrapCString("0x123456=value");
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+ char *actual = ccnxNameLabel_ToString(label);
+
+ assertTrue(parcBuffer_Position(buffer) == 9, "Expected position to be 9, actual %zd", parcBuffer_Position(buffer));
+ char *expected = "1193046=";
+ assertTrue(strcmp(expected, actual) == 0, "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse_UknownMnemonicLabel)
+{
+ PARCBuffer *buffer = parcBuffer_WrapCString("abc=value");
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+
+ assertFalse(ccnxNameLabel_IsValid(label), "Expected an invalid CCNxNameLabel from an invalid specification.");
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse_KnownLabel)
+{
+ PARCBuffer *buffer = parcBuffer_WrapCString("Serial=value");
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+ char *actual = ccnxNameLabel_ToString(label);
+ parcMemory_Deallocate((void **) &actual);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse_DefaultLabel)
+{
+ PARCBuffer *buffer = parcBuffer_WrapCString("value");
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+ char *actual = ccnxNameLabel_ToString(label);
+ char *expected = "Name=";
+ assertTrue(strcmp(expected, actual) == 0, "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameType_Parse_EmptyLabel)
+{
+ PARCBuffer *buffer = parcBuffer_WrapCString("=value");
+ CCNxNameLabel *label = ccnxNameLabel_Parse(buffer);
+ assertNull(label, "Expected a NULL return value from ccnxNameLabel_Parse for the invalid string '=value'");
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_FIXTURE(Errors)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Errors)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Errors)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_NameType);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_NameSegment.c b/libccnx-common/ccnx/common/test/test_ccnx_NameSegment.c
new file mode 100644
index 00000000..b691c52a
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_NameSegment.c
@@ -0,0 +1,739 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+#include <config.h>
+#include <stdio.h>
+#include <LongBow/unit-test.h>
+
+#include <parc/algol/parc_Memory.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Framework.
+#include "../ccnx_NameSegment.c"
+
+LONGBOW_TEST_RUNNER(ccnx_NameComponent)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_NameComponent)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_NameComponent)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_CreateTypeValue);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_Copy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_Copy_WithParameter);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_Length);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_GetType);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ParseURISegment);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ToString_META);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ToString_APP0);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ToString_NAME);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ToString_NAME_NotDefault);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ToString_SERIAL);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_RawNAME);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ToString_APP256);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ToString_PAYLOADHASH);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_NAME);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_META);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_list);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_UnknownLabel);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_ZeroLength);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_Compare_Contract);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_Equals_Contract);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_HashCode);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_Display);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_IsValid);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_IsValid_NULL);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegment_IsValid_InnerNULL1);
+}
+
+static uint32_t initialAllocationCount;
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ initialAllocationCount = parcMemory_Outstanding();
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t remainingAllocations = parcMemory_Outstanding() - initialAllocationCount;
+ if (remainingAllocations > 0) {
+ printf("%s leaks memory by %u allocations\n", longBowTestCase_GetName(testCase), remainingAllocations);
+ parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_IsValid)
+{
+ PARCBuffer *value = parcBuffer_WrapCString("Test");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, value);
+
+ assertTrue(ccnxNameSegment_IsValid(segment), "Expected a valid CCNxNameSegment.");
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&value);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_IsValid_NULL)
+{
+ assertFalse(ccnxNameSegment_IsValid(NULL), "Expected NULL to be an invalid CCNxNameSegment.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_IsValid_InnerNULL1)
+{
+ PARCBuffer *buf = parcBuffer_WrapCString("Test");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+
+ // Hit the NULL case
+ PARCBuffer *oldBuffer = segment->value;
+ segment->value = NULL;
+
+ assertFalse(ccnxNameSegment_IsValid(segment),
+ "Expected a name segment with a NULL value to be invalid.");
+
+ segment->value = oldBuffer;
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_CreateTypeValue)
+{
+ PARCBuffer *buf = parcBuffer_WrapCString("Test");
+
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+ assertNotNull(segment, "Expected non-null");
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_CreateTypeParameterValue)
+{
+ PARCBuffer *parameter = parcBuffer_WrapCString("param");
+ PARCBuffer *value = parcBuffer_WrapCString("Value");
+
+ CCNxNameLabel *label = ccnxNameLabel_Create(CCNxNameLabelType_NAME, parameter);
+ CCNxNameSegment *segment = ccnxNameSegment_CreateLabelValue(label, value);
+ ccnxNameLabel_Release(&label);
+ assertNotNull(segment, "Expected non-null");
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&parameter);
+ parcBuffer_Release(&value);
+}
+
+// Convert the tests to use this table, instead of individual tests.
+struct nameSegments {
+ char *lciSegment;
+ CCNxNameLabelType nameType;
+ char *parameter;
+ char *value;
+} nameSegment[] = {
+ { .lciSegment = "NAME",
+ .nameType = CCNxNameLabelType_NAME, .parameter = NULL, .value = "NAME", },
+ { .lciSegment = CCNxNameLabel_Name "=" "NAME",
+ .nameType = CCNxNameLabelType_NAME, .parameter = NULL, .value = "NAME", },
+ { .lciSegment = CCNxNameLabel_Chunk "=" "Chunk",
+ .nameType = CCNxNameLabelType_CHUNK, .parameter = NULL, .value = "Chunk", },
+ { .lciSegment = CCNxNameLabel_Chunk ":param=" "Chunk",
+ .nameType = CCNxNameLabelType_CHUNK, .parameter = "param", .value = "Chunk", },
+ { .lciSegment = CCNxNameLabel_App ":100=" "app100",
+ .nameType = CCNxNameLabelType_App(100), .parameter = NULL, .value = "app100", },
+ { .lciSegment = NULL },
+};
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_list)
+{
+ for (struct nameSegments *p = &nameSegment[0]; p->lciSegment != NULL; p++) {
+ PARCURISegment *segment = parcURISegment_Parse(p->lciSegment, NULL);
+
+ CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(segment);
+
+ CCNxNameLabelType type = ccnxNameSegment_GetType(actual);
+ assertTrue(p->nameType == type, "Expected %04x, actual %04x", p->nameType, type);
+
+ PARCBuffer *valueValue = parcBuffer_WrapCString(p->value);
+ PARCBuffer *expectedParam = p->parameter == NULL ? NULL : parcBuffer_WrapCString(p->parameter);
+ CCNxNameLabel *label = ccnxNameLabel_Create(p->nameType, expectedParam);
+ CCNxNameSegment *expected = ccnxNameSegment_CreateLabelValue(label, valueValue);
+ ccnxNameLabel_Release(&label);
+
+ parcBuffer_Release(&valueValue);
+ if (expectedParam != NULL) {
+ parcBuffer_Release(&expectedParam);
+ }
+
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(actual);
+ assertTrue(ccnxNameSegment_Equals(expected, actual),
+ "Expected '%s' Actual, '%s", expectedString, actualString);
+ parcMemory_Deallocate((void **) &expectedString);
+ parcMemory_Deallocate((void **) &actualString);
+
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+ parcURISegment_Release(&segment);
+ }
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_RawNAME)
+{
+ char *lciSegment = "NAME";
+ PARCURISegment *segment = parcURISegment_Parse(lciSegment, NULL);
+
+ CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(segment);
+
+ CCNxNameLabelType type = ccnxNameSegment_GetType(actual);
+ assertTrue(CCNxNameLabelType_NAME == type, "Expected %04x, actual %04x", CCNxNameLabelType_NAME, type);
+
+ PARCBuffer *buf = parcBuffer_WrapCString("NAME");
+ CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+
+ assertTrue(ccnxNameSegment_Equals(expected, actual), "Error in ccnxNameSegment_ParseURISegment")
+ {
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(expected);
+ fprintf(stderr, "Expected '%s', actual '%s'", expectedString, actualString);
+ parcMemory_Deallocate((void **) expectedString);
+ parcMemory_Deallocate((void **) actualString);
+ };
+
+ parcBuffer_Release(&buf);
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+ parcURISegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_NAME)
+{
+ char *lciSegment = CCNxNameLabel_Name "=" "NAME";
+ PARCURISegment *segment = parcURISegment_Parse(lciSegment, NULL);
+
+ CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(segment);
+
+ CCNxNameLabelType type = ccnxNameSegment_GetType(actual);
+ assertTrue(CCNxNameLabelType_NAME == type, "Expected %04x, actual %04x", CCNxNameLabelType_NAME, type);
+
+ PARCBuffer *buf = parcBuffer_WrapCString("NAME");
+ CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+
+ assertTrue(ccnxNameSegment_Equals(expected, actual), "Error in ccnxNameSegment_ParseURISegment")
+ {
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(expected);
+ fprintf(stderr, "Expected '%s', actual '%s'", expectedString, actualString);
+ parcMemory_Deallocate((void **) expectedString);
+ parcMemory_Deallocate((void **) actualString);
+ };
+
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+ parcURISegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_META)
+{
+ char *lciSegment = CCNxNameLabel_ChunkMeta "=" "META";
+ PARCURISegment *segment = parcURISegment_Parse(lciSegment, NULL);
+
+ CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(segment);
+
+ CCNxNameLabelType type = ccnxNameSegment_GetType(actual);
+ assertTrue(CCNxNameLabelType_CHUNKMETA == type, "Expected 0x%04x, actual 0x%04x", CCNxNameLabelType_CHUNKMETA, type);
+
+ PARCBuffer *buf = parcBuffer_WrapCString("META");
+
+ CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_CHUNKMETA, buf);
+
+ assertTrue(ccnxNameSegment_Equals(expected, actual), "Error in ccnxNameSegment_ParseURISegment")
+ {
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(expected);
+ fprintf(stderr, "Expected '%s', actual '%s'", expectedString, actualString);
+ parcMemory_Deallocate((void **) expectedString);
+ parcMemory_Deallocate((void **) actualString);
+ };
+
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+ parcURISegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_UnknownLabel)
+{
+ char *lciSegment = "unknown:param" "=" "abcdef";
+ PARCURISegment *segment = parcURISegment_Parse(lciSegment, NULL);
+
+ CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(segment);
+
+ parcURISegment_Release(&segment);
+
+ assertNull(actual, "Expected NULL return from ccnxNameSegment_ParseURISegment");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_APP0)
+{
+ char *lciSegment = CCNxNameLabelType_LabelApp(0) "=" "APP0";
+ PARCURISegment *segment = parcURISegment_Parse(lciSegment, NULL);
+
+ CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(segment);
+
+ CCNxNameLabelType type = ccnxNameSegment_GetType(actual);
+ assertTrue(CCNxNameLabelType_App(0) == type, "Expected %04x, actual %04x", CCNxNameLabelType_App(0), type);
+
+ PARCBuffer *buf = parcBuffer_WrapCString("APP0");
+
+ CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_App(0), buf);
+ assertTrue(ccnxNameSegment_Equals(expected, actual), "Error in ccnxNameSegment_ParseURISegment")
+ {
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(expected);
+ fprintf(stderr, "Expected '%s', actual '%s'", expectedString, actualString);
+ parcMemory_Deallocate((void **) expectedString);
+ parcMemory_Deallocate((void **) actualString);
+ };
+
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+ parcURISegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ParseURISegment_APP256)
+{
+ char *lciSegment = CCNxNameLabelType_LabelApp(255) "=" "APP255";
+ PARCURISegment *segment = parcURISegment_Parse(lciSegment, NULL);
+
+ CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(segment);
+
+ CCNxNameLabelType type = ccnxNameSegment_GetType(actual);
+ assertTrue(CCNxNameLabelType_App(255) == type, "Expected %04x, actual %04x", CCNxNameLabelType_App(255), type);
+
+ PARCBuffer *buf = parcBuffer_WrapCString("APP255");
+ CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_App(255), buf);
+ parcBuffer_Release(&buf);
+
+ assertTrue(ccnxNameSegment_Equals(expected, actual), "Error in ccnxNameSegment_ParseURISegment")
+ {
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(expected);
+ fprintf(stderr, "Expected '%s', actual '%s'", expectedString, actualString);
+ parcMemory_Deallocate((void **) expectedString);
+ parcMemory_Deallocate((void **) actualString);
+ };
+
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+ parcURISegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ParseURISegment)
+{
+ char *lciSegment = CCNxNameLabel_Name "=" "abcde";
+ PARCURISegment *segment = parcURISegment_Parse(lciSegment, NULL);
+
+ CCNxNameSegment *actual = ccnxNameSegment_ParseURISegment(segment);
+
+ CCNxNameLabelType type = ccnxNameSegment_GetType(actual);
+ assertTrue(CCNxNameLabelType_NAME == type,
+ "Expected %04x, actual %04x", 0x20, type);
+
+ PARCBuffer *buf = parcBuffer_WrapCString("abcde");
+
+ CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+
+ assertTrue(ccnxNameSegment_Equals(expected, actual), "Error in ccnxNameSegment_ParseURISegment")
+ {
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(expected);
+ fprintf(stderr, "Expected '%s', actual '%s'", expectedString, actualString);
+ parcMemory_Deallocate((void **) expectedString);
+ parcMemory_Deallocate((void **) actualString);
+ };
+
+ ccnxNameSegment_Release(&expected);
+ parcBuffer_Release(&buf);
+ ccnxNameSegment_Release(&actual);
+ parcURISegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ZeroLength)
+{
+ char *begin = "";
+
+ PARCBuffer *buffer = parcBuffer_WrapCString(begin);
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buffer);
+
+ assertNotNull(segment, "Expected non-null");
+ assertTrue(ccnxNameSegment_Length(segment) == 0, "Failed to create a zero length segment");
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_Equals_Contract)
+{
+ PARCBuffer *bufX = parcBuffer_WrapCString("Test");
+ PARCBuffer *bufY = parcBuffer_WrapCString("Test");
+ PARCBuffer *bufZ = parcBuffer_WrapCString("Test");
+ PARCBuffer *bufU1 = parcBuffer_WrapCString("Test");
+ PARCBuffer *bufU2 = parcBuffer_WrapCString("blah");
+
+ CCNxNameSegment *x = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufX);
+ CCNxNameSegment *y = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufY);
+ CCNxNameSegment *z = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufZ);
+ CCNxNameSegment *u1 = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_CHUNKMETA, bufU1);
+ CCNxNameSegment *u2 = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufU2);
+
+ assertEqualsContract(ccnxNameSegment_Equals, x, y, z, u1, u2, NULL);
+
+ ccnxNameSegment_Release(&x);
+ ccnxNameSegment_Release(&y);
+ ccnxNameSegment_Release(&z);
+ ccnxNameSegment_Release(&u1);
+ ccnxNameSegment_Release(&u2);
+
+ parcBuffer_Release(&bufX);
+ parcBuffer_Release(&bufY);
+ parcBuffer_Release(&bufZ);
+ parcBuffer_Release(&bufU1);
+ parcBuffer_Release(&bufU2);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_Compare_Contract)
+{
+ char *aString = "foo";
+ PARCBuffer *bufA = parcBuffer_WrapCString(aString);
+ CCNxNameSegment *a = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufA);
+
+ PARCBuffer *bufFoo = parcBuffer_WrapCString("foo");
+ PARCBuffer *bufFon = parcBuffer_WrapCString("fon");
+ PARCBuffer *bufFo = parcBuffer_WrapCString("fo");
+ PARCBuffer *bufFop = parcBuffer_WrapCString("fop");
+ PARCBuffer *bufFooa = parcBuffer_WrapCString("fooa");
+
+ CCNxNameSegment **equivalents = (CCNxNameSegment *[]) {
+ ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufFoo),
+ NULL
+ };
+ CCNxNameSegment **lessers = (CCNxNameSegment *[]) {
+ ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufFon),
+ ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufFo),
+ NULL
+ };
+ CCNxNameSegment **greaters = (CCNxNameSegment *[]) {
+ ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufFop),
+ ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufFooa),
+ NULL
+ };
+
+ assertCompareToContract(ccnxNameSegment_Compare, a, equivalents, lessers, greaters);
+
+ ccnxNameSegment_Release(&a);
+
+ for (int i = 0; equivalents[i] != NULL; i++) {
+ ccnxNameSegment_Release(&equivalents[i]);
+ }
+ for (int i = 0; lessers[i] != NULL; i++) {
+ ccnxNameSegment_Release(&lessers[i]);
+ }
+ for (int i = 0; greaters[i] != NULL; i++) {
+ ccnxNameSegment_Release(&greaters[i]);
+ }
+
+ parcBuffer_Release(&bufFoo);
+ parcBuffer_Release(&bufFon);
+ parcBuffer_Release(&bufFo);
+ parcBuffer_Release(&bufFop);
+ parcBuffer_Release(&bufFooa);
+ parcBuffer_Release(&bufA);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_Length)
+{
+ char *expected = "foo";
+
+ PARCBuffer *buffer = parcBuffer_WrapCString(expected);
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buffer);
+
+ size_t actual = ccnxNameSegment_Length(segment);
+
+ ccnxNameSegment_Release(&segment);
+
+ assertTrue(strlen(expected) == actual,
+ "Expected %zd, actual %zd", strlen(expected), actual);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_Copy)
+{
+ PARCBuffer *buf = parcBuffer_WrapCString("foo");
+ CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+ CCNxNameSegment *actual = ccnxNameSegment_Copy(expected);
+ CCNxNameSegment *acquiredCopy = ccnxNameSegment_Acquire(expected);
+
+ assertTrue(expected != actual, "Expected a distinct copy of the original.");
+
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(actual);
+ char *acquiredString = ccnxNameSegment_ToString(acquiredCopy);
+ assertTrue(ccnxNameSegment_Equals(expected, actual), "Expected %s, actual %s", expectedString, actualString);
+ assertTrue(ccnxNameSegment_Equals(expected, acquiredCopy), "Expected %s, actual %s", expectedString, acquiredString);
+
+ parcMemory_Deallocate((void **) &expectedString);
+ parcMemory_Deallocate((void **) &actualString);
+ parcMemory_Deallocate((void **) &acquiredString);
+
+ ccnxNameSegment_Release(&acquiredCopy);
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_Copy_WithParameter)
+{
+ PARCBuffer *value = parcBuffer_WrapCString("value");
+ PARCBuffer *parameter = parcBuffer_WrapCString("param");
+ CCNxNameLabel *label = ccnxNameLabel_Create(CCNxNameLabelType_NAME, parameter);
+ CCNxNameSegment *expected = ccnxNameSegment_CreateLabelValue(label, value);
+ ccnxNameLabel_Release(&label);
+ parcBuffer_Release(&value);
+ parcBuffer_Release(&parameter);
+
+ CCNxNameSegment *actual = ccnxNameSegment_Copy(expected);
+
+ assertTrue(expected != actual, "Expected a distinct copy of the original.");
+
+ char *expectedString = ccnxNameSegment_ToString(expected);
+ char *actualString = ccnxNameSegment_ToString(actual);
+ assertTrue(ccnxNameSegment_Equals(expected, actual), "Expected '%s', actual '%s'", expectedString, actualString);
+
+ parcMemory_Deallocate((void **) &expectedString);
+ parcMemory_Deallocate((void **) &actualString);
+
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_GetType)
+{
+ PARCBuffer *buf = parcBuffer_WrapCString("hello");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+
+ assertTrue(CCNxNameLabelType_NAME == ccnxNameSegment_GetType(segment),
+ "Expected type %d, actual %d", CCNxNameLabelType_NAME, ccnxNameSegment_GetType(segment));
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ToString_META)
+{
+ char *expected = CCNxNameLabel_ChunkMeta "=META";
+ PARCBuffer *buf = parcBuffer_WrapCString("META");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_CHUNKMETA, buf);
+ char *actual = ccnxNameSegment_ToString(segment);
+ assertTrue(strcmp(expected, actual) == 0,
+ "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ToString_PAYLOADHASH)
+{
+ char *expected = CCNxNameLabel_InterestPayloadId "=PAYLOADHASH";
+ PARCBuffer *buf = parcBuffer_WrapCString("PAYLOADHASH");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_PAYLOADID, buf);
+
+ char *actual = ccnxNameSegment_ToString(segment);
+ assertTrue(strcmp(expected, actual) == 0,
+ "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ToString_NAME)
+{
+ PARCBuffer *buf = parcBuffer_WrapCString("NAME");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+
+ // Note that this is different than the other tests for segments because a NAME name segment
+ // is the default type and as such the string representation doesn't include the leading label specification.
+ char *expected = "NAME";
+ char *actual = ccnxNameSegment_ToString(segment);
+ assertTrue(strcmp(expected, actual) == 0,
+ "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ToString_NAME_NotDefault)
+{
+ PARCBuffer *value = parcBuffer_WrapCString("MiISAg==");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, value);
+
+ // Note that this is different than the other tests for segments because a NAME name segment
+ // is the default type and as such the string representation doesn't include the leading label specification.
+ char *expected = CCNxNameLabel_Name "=" "MiISAg%3D%3D";
+ char *actual = ccnxNameSegment_ToString(segment);
+ assertTrue(strcmp(expected, actual) == 0,
+ "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&value);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ToString_APP0)
+{
+ char *expected = CCNxNameLabelType_LabelApp(0) "=APP0";
+ PARCBuffer *buf = parcBuffer_WrapCString("APP0");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_App(0), buf);
+
+ char *actual = ccnxNameSegment_ToString(segment);
+ assertTrue(strcmp(expected, actual) == 0,
+ "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ToString_SERIAL)
+{
+ char *expected = CCNxNameLabel_Serial "=serialnumber";
+ PARCBuffer *buf = parcBuffer_WrapCString("serialnumber");
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_SERIAL, buf);
+
+ char *actual = ccnxNameSegment_ToString(segment);
+ assertTrue(strcmp(expected, actual) == 0,
+ "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_ToString_APP256)
+{
+ char *expected = CCNxNameLabelType_LabelApp(255) "=APP255";
+ PARCBuffer *buf = parcBuffer_WrapCString("APP255");
+
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_App(255), buf);
+ char *actual = ccnxNameSegment_ToString(segment);
+ assertTrue(strcmp(expected, actual) == 0,
+ "Expected %s, actual %s", expected, actual);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_HashCode)
+{
+ PARCBuffer *bufA = parcBuffer_WrapCString("Test");
+
+ CCNxNameSegment *segmentA = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufA);
+ CCNxNameSegment *segmentB = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_CHUNKMETA, bufA);
+
+ assertFalse(ccnxNameSegment_HashCode(segmentA) == ccnxNameSegment_HashCode(segmentB),
+ "Expected different hash codes");
+
+ PARCBuffer *bufC = parcBuffer_WrapCString("Not Test");
+
+ CCNxNameSegment *segmentC = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufC);
+
+ assertFalse(ccnxNameSegment_HashCode(segmentA) == ccnxNameSegment_HashCode(segmentC),
+ "Expected different hash codes");
+
+ CCNxNameSegment *segmentD = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, bufA);
+
+ assertTrue(ccnxNameSegment_HashCode(segmentD) == ccnxNameSegment_HashCode(segmentA),
+ "Expected same hash codes");
+
+ ccnxNameSegment_Release(&segmentA);
+ ccnxNameSegment_Release(&segmentB);
+ ccnxNameSegment_Release(&segmentC);
+ ccnxNameSegment_Release(&segmentD);
+
+ parcBuffer_Release(&bufA);
+ parcBuffer_Release(&bufC);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegment_Display)
+{
+ PARCBuffer *buf = parcBuffer_WrapCString("Test");
+
+ CCNxNameSegment *segment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buf);
+
+ ccnxNameSegment_Display(segment, 0);
+
+ ccnxNameSegment_Release(&segment);
+ parcBuffer_Release(&buf);
+}
+
+LONGBOW_TEST_CASE_EXPECTS(Global, ccnxNameSegment_AssertValid_Invalid, .event = &LongBowAssertEvent)
+{
+ ccnxNameSegment_AssertValid(NULL);
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_NameComponent);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_NameSegmentNumber.c b/libccnx-common/ccnx/common/test/test_ccnx_NameSegmentNumber.c
new file mode 100755
index 00000000..fb14ef39
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_NameSegmentNumber.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+#include "../ccnx_NameSegmentNumber.c"
+
+#include <LongBow/unit-test.h>
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+
+LONGBOW_TEST_RUNNER(test_ccnx_NameSegmentNumber)
+{
+ // The following Test Fixtures will run their corresponding Test Cases.
+ // Test Fixtures are run in the order specified, but all tests should be idempotent.
+ // Never rely on the execution order of tests or share state between them.
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(test_ccnx_NameSegmentNumber)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(test_ccnx_NameSegmentNumber)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_Create64bits);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_Create56bits);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_Create48bits);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_Create40bits);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_Create32bits);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_Create24bits);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_Create16bits);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_Create8bits);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_BorderCases);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_IsValid);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_IsValid_False);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxNameSegmentNumber_AssertValid);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDOUT_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_Create64bits)
+{
+ uint64_t expected = 0x123456789ABCDEF0;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ uint64_t actual = ccnxNameSegmentNumber_Value(segment);
+
+ assertTrue(expected == actual, "Expected 0x%" PRIX64 " actual 0x%" PRIX64 "", expected, actual);
+
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_Create56bits)
+{
+ uint64_t expected = 0x123456789ABCDE;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ uint64_t actual = ccnxNameSegmentNumber_Value(segment);
+
+ assertTrue(expected == actual, "Expected 0x%" PRIX64 " actual 0x%" PRIX64 "", expected, actual);
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_Create48bits)
+{
+ uint64_t expected = 0x123456789ABC;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ uint64_t actual = ccnxNameSegmentNumber_Value(segment);
+
+ assertTrue(expected == actual, "Expected 0x%" PRIX64 " actual 0x%" PRIX64 "", expected, actual);
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_Create40bits)
+{
+ uint64_t expected = 0x123456789A;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ uint64_t actual = ccnxNameSegmentNumber_Value(segment);
+
+ assertTrue(expected == actual, "Expected 0x%" PRIX64 " actual 0x%" PRIX64 "", expected, actual);
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_Create32bits)
+{
+ uint64_t expected = 0x12345678;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ uint64_t actual = ccnxNameSegmentNumber_Value(segment);
+
+ assertTrue(expected == actual, "Expected 0x%" PRIX64 " actual 0x%" PRIX64 "", expected, actual);
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_Create24bits)
+{
+ uint64_t expected = 0x123456;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ uint64_t actual = ccnxNameSegmentNumber_Value(segment);
+
+ assertTrue(expected == actual, "Expected 0x%" PRIX64 " actual 0x%" PRIX64 "", expected, actual);
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_Create16bits)
+{
+ uint64_t expected = 0x1234;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ uint64_t actual = ccnxNameSegmentNumber_Value(segment);
+
+ assertTrue(expected == actual, "Expected 0x%" PRIX64 " actual 0x%" PRIX64 "", expected, actual);
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_Create8bits)
+{
+ uint64_t expected = 0x12;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ uint64_t actual = ccnxNameSegmentNumber_Value(segment);
+
+ assertTrue(expected == actual, "Expected 0x%" PRIX64 " actual 0x%" PRIX64 "", expected, actual);
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_BorderCases)
+{
+ struct test_struct {
+ uint64_t value;
+ size_t length;
+ uint8_t *encoded;
+ } test_vector[] = {
+ { .value = 0x0000000000000000ULL, .length = 1, .encoded = (uint8_t[1]) { 0x00 } },
+ { .value = 0x0000000000000001ULL, .length = 1, .encoded = (uint8_t[1]) { 0x01 } },
+ { .value = 0x00000000000000FFULL, .length = 1, .encoded = (uint8_t[1]) { 0xFF } },
+ { .value = 0x0000000000000100ULL, .length = 2, .encoded = (uint8_t[2]) { 0x01, 0x00} },
+ { .value = 0x0100000000000100ULL, .length = 8, .encoded = (uint8_t[8]) { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00} },
+ { .value = 0x8000000000000100ULL, .length = 8, .encoded = (uint8_t[8]) { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00} },
+ { .value = 0xFFFFFFFFFFFFFFFFULL, .length = 8, .encoded = (uint8_t[8]) { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} },
+ { .value = 0, .length = 0, .encoded = NULL }
+ };
+
+ for (int i = 0; test_vector[i].encoded != NULL; i++) {
+ PARCBuffer *buffer =
+ parcBuffer_Wrap(test_vector[i].encoded, test_vector[i].length, 0, test_vector[i].length);
+ CCNxNameSegment *expected = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_NAME, buffer);
+
+ CCNxNameSegment *actual = ccnxNameSegmentNumber_Create(CCNxNameLabelType_NAME, test_vector[i].value);
+
+ assertTrue(ccnxNameSegment_Equals(expected, actual),
+ "Buffers do not match: test_vector[%d] value %" PRIX64 " Expected %" PRIX64 " actual %" PRIX64 "",
+ i,
+ test_vector[i].value,
+ ccnxNameSegmentNumber_Value(expected),
+ ccnxNameSegmentNumber_Value(actual));
+
+ ccnxNameSegment_Release(&expected);
+ ccnxNameSegment_Release(&actual);
+ parcBuffer_Release(&buffer);
+ }
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_AssertValid)
+{
+ uint64_t expected = 0x12;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ ccnxNameSegmentNumber_AssertValid(segment);
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_IsValid)
+{
+ uint64_t expected = 0x12;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ assertTrue(ccnxNameSegmentNumber_IsValid(segment), "Expected the CCNxNameSegment to be valid.");
+ ccnxNameSegment_Release(&segment);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxNameSegmentNumber_IsValid_False)
+{
+ uint64_t expected = 0x12;
+ CCNxNameSegment *segment = ccnxNameSegmentNumber_Create(CCNxNameLabelType_CHUNK, expected);
+
+ PARCBuffer *value = ccnxNameSegment_GetValue(segment);
+ parcBuffer_SetPosition(value, parcBuffer_Limit(value)); // Wreck the buffer by making it zero length.
+
+ assertFalse(ccnxNameSegmentNumber_IsValid(segment), "Expected the CCNxNameSegment to be valid.");
+ ccnxNameSegment_Release(&segment);
+}
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_ccnx_NameSegmentNumber);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_TimeStamp.c b/libccnx-common/ccnx/common/test/test_ccnx_TimeStamp.c
new file mode 100755
index 00000000..d65ebd64
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_TimeStamp.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+#include <ccnx/common/ccnx_TimeStamp.c>
+
+#include <inttypes.h>
+#include <time.h>
+
+#include <LongBow/unit-test.h>
+#include <parc/algol/parc_SafeMemory.h>
+
+
+LONGBOW_TEST_RUNNER(ccnx_TimeStamp)
+{
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Local);
+}
+
+LONGBOW_TEST_RUNNER_SETUP(ccnx_TimeStamp)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_TimeStamp)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTimeStamp_CreateFromCurrentUTCTime);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTimeStamp_CreateFromTimespec);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTimeStamp_CreateFromMillisecondsSinceEpoch);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTimeStamp_Copy);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTimeStamp_Equals);
+
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTimeStamp_AsNanoSeconds);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTimeStamp_CreateFromNanosecondsSinceEpoch);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxTimeStamp_ToString);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTimeStamp_CreateFromCurrentUTCTime)
+{
+ CCNxTimeStamp *timeStamp = ccnxTimeStamp_CreateFromCurrentUTCTime();
+ assertNotNull(timeStamp, "Expected a non-null response");
+
+ ccnxTimeStamp_Release(&timeStamp);
+ assertNull(timeStamp, "Release failed to NULL the pointer.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTimeStamp_CreateFromTimespec)
+{
+ struct timespec time = { .tv_sec = 1, .tv_nsec = 1 };
+
+ CCNxTimeStamp *timeStamp = ccnxTimeStamp_CreateFromTimespec(&time);
+ assertNotNull(timeStamp, "Expected a non-null response");
+
+ struct timespec actualTime = ccnxTimeStamp_AsTimespec(timeStamp);
+
+ assertTrue(time.tv_sec == actualTime.tv_sec && time.tv_nsec == actualTime.tv_nsec, "Expected timespec to be equal.");
+
+ ccnxTimeStamp_Release(&timeStamp);
+ assertNull(timeStamp, "Release failed to NULL the pointer.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTimeStamp_CreateFromMillisecondsSinceEpoch)
+{
+ time_t theTimeInSeconds;
+ time(&theTimeInSeconds);
+
+ CCNxTimeStamp *timeStamp = ccnxTimeStamp_CreateFromMillisecondsSinceEpoch((uint64_t) theTimeInSeconds * 1000);
+ assertNotNull(timeStamp, "Expected a non-null response");
+
+ struct timespec timeSpec = ccnxTimeStamp_AsTimespec(timeStamp);
+
+ assertTrue(theTimeInSeconds == timeSpec.tv_sec, "Expected %ld, actual %ld", theTimeInSeconds, timeSpec.tv_sec);
+
+ assertTrue(0 == timeSpec.tv_nsec, "Expected %d, actual %ld", 0, timeSpec.tv_nsec);
+
+ ccnxTimeStamp_Release(&timeStamp);
+ assertNull(timeStamp, "Release failed to NULL the pointer.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTimeStamp_CreateFromNanosecondsSinceEpoch)
+{
+ uint64_t expected = 1099511627776ULL;
+
+ CCNxTimeStamp *timeStamp = ccnxTimeStamp_CreateFromNanosecondsSinceEpoch(expected);
+
+ uint64_t actual = ccnxTimeStamp_AsNanoSeconds(timeStamp);
+
+ assertTrue(expected == actual, "Expected %" PRIu64 " actual %" PRIu64, expected, actual);
+
+ ccnxTimeStamp_Release(&timeStamp);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTimeStamp_Equals)
+{
+ time_t theTimeInSeconds;
+ time(&theTimeInSeconds);
+
+ CCNxTimeStamp *x = ccnxTimeStamp_CreateFromMillisecondsSinceEpoch(theTimeInSeconds * 1000);
+ CCNxTimeStamp *y = ccnxTimeStamp_CreateFromMillisecondsSinceEpoch(theTimeInSeconds * 1000);
+ CCNxTimeStamp *z = ccnxTimeStamp_CreateFromMillisecondsSinceEpoch(theTimeInSeconds * 1000);
+ CCNxTimeStamp *u1 = ccnxTimeStamp_CreateFromMillisecondsSinceEpoch((theTimeInSeconds + 1) * 1000);
+ CCNxTimeStamp *u2 = ccnxTimeStamp_CreateFromMillisecondsSinceEpoch((theTimeInSeconds + 2) * 1000);
+
+ assertEqualsContract(ccnxTimeStamp_Equals, x, y, z, u1, u2)
+
+ ccnxTimeStamp_Release(&x);
+ ccnxTimeStamp_Release(&y);
+ ccnxTimeStamp_Release(&z);
+ ccnxTimeStamp_Release(&u1);
+ ccnxTimeStamp_Release(&u2);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTimeStamp_Copy)
+{
+ time_t theTime;
+ time(&theTime);
+
+ CCNxTimeStamp *timeStamp = ccnxTimeStamp_CreateFromMillisecondsSinceEpoch(theTime);
+ assertNotNull(timeStamp, "Expected a non-null response");
+
+ CCNxTimeStamp *copy = ccnxTimeStamp_Copy(timeStamp);
+
+ char *expected = ccnxTimeStamp_ToString(timeStamp);
+ char *actual = ccnxTimeStamp_ToString(copy);
+ assertTrue(ccnxTimeStamp_Equals(timeStamp, copy),
+ "Expected %s actual %s.", expected, actual);
+ parcMemory_Deallocate((void **) &expected);
+ parcMemory_Deallocate((void **) &actual);
+
+ ccnxTimeStamp_Release(&timeStamp);
+ ccnxTimeStamp_Release(&copy);
+ assertNull(timeStamp, "Destroy failed to NULL the pointer.");
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTimeStamp_AsNanoSeconds)
+{
+ uint64_t expected = 1099501627776ULL;
+
+ CCNxTimeStamp *timeStamp = ccnxTimeStamp_CreateFromNanosecondsSinceEpoch(expected);
+
+ uint64_t actual = ccnxTimeStamp_AsNanoSeconds(timeStamp);
+
+ assertTrue(expected == actual, "Expected %" PRIu64 " actual %" PRIu64, expected, actual);
+
+ ccnxTimeStamp_Release(&timeStamp);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxTimeStamp_ToString)
+{
+ CCNxTimeStamp *timeStamp = ccnxTimeStamp_CreateFromCurrentUTCTime();
+ assertNotNull(timeStamp, "Expected a non-null response");
+
+ char *string = ccnxTimeStamp_ToString(timeStamp);
+ assertNotNull(string, "Expected non-null result.");
+
+ parcMemory_Deallocate((void **) &string);
+
+ ccnxTimeStamp_Release(&timeStamp);
+ assertNull(timeStamp, "Destroy failed to NULL the pointer.");
+ // See case 1016
+ testUnimplemented("This test is unimplemented");
+}
+
+LONGBOW_TEST_FIXTURE(Local)
+{
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Local)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Local)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+int
+main(int argc, char *argv[argc])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_TimeStamp);
+ exit(longBowMain(argc, argv, testRunner, NULL));
+}
diff --git a/libccnx-common/ccnx/common/test/test_ccnx_WireFormatMessage.c b/libccnx-common/ccnx/common/test/test_ccnx_WireFormatMessage.c
new file mode 100755
index 00000000..43b27dc2
--- /dev/null
+++ b/libccnx-common/ccnx/common/test/test_ccnx_WireFormatMessage.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ */
+
+// Include the file(s) containing the functions to be tested.
+// This permits internal static functions to be visible to this Test Runner.
+#include "../ccnx_WireFormatMessage.c"
+
+#include <stdio.h>
+
+#include <LongBow/unit-test.h>
+
+#include <parc/algol/parc_SafeMemory.h>
+
+#include <ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_TlvDictionary.h>
+
+#include <ccnx/common/codec/ccnxCodec_TlvPacket.h>
+#include <ccnx/common/codec/schema_v1/testdata/v1_interest_nameA.h>
+#include <ccnx/common/ccnx_ContentObject.h>
+
+
+LONGBOW_TEST_RUNNER(ccnx_WireFormatMessage)
+{
+ parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory);
+
+ LONGBOW_RUN_TEST_FIXTURE(Global);
+ LONGBOW_RUN_TEST_FIXTURE(Static);
+}
+
+// The Test Runner calls this function once before any Test Fixtures are run.
+LONGBOW_TEST_RUNNER_SETUP(ccnx_WireFormatMessage)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+// The Test Runner calls this function once after all the Test Fixtures are run.
+LONGBOW_TEST_RUNNER_TEARDOWN(ccnx_WireFormatMessage)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE(Global)
+{
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_AcquireRelease);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_AssertValid);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_Create);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_FromContentObjectPacketType);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_FromControlPacketType);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_FromInterestPacketType);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_FromInterestPacketTypeIoVec);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_GetDictionary);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_PutGetIoVec);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_GetWireFormatBuffer);
+ //
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_CreateContentObjectHash);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_HashProtectedRegion);
+ //
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_PutWireFormatBuffer);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_SetProtectedRegionLength);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_SetProtectedRegionStart);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_WriteToFile);
+ LONGBOW_RUN_TEST_CASE(Global, ccnxWireFormatMessage_SetHopLimit);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Global)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Global)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_AcquireRelease)
+{
+ PARCBuffer *buffer = parcBuffer_Allocate(10);
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromInterestPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ CCNxWireFormatMessage *ref = ccnxWireFormatMessage_Acquire(message);
+ assertNotNull(ref, "Expected a non-NULL reference to be acquired");
+
+ ccnxWireFormatMessage_Release(&message);
+ assertNotNull(ref, "Expected a non-NULL reference to be acquired");
+ assertNull(message, "Expeced original message to be NULL");
+
+ ccnxWireFormatMessage_Release(&ref);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_AssertValid)
+{
+ PARCBuffer *wireFormat = parcBuffer_Wrap(v1_interest_nameA, sizeof(v1_interest_nameA), 0, sizeof(v1_interest_nameA));
+
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_Create(wireFormat);
+ assertNotNull(message, "Got null CCNxWireFormatMessage, after attempting to create with buffer");
+
+ ccnxWireFormatMessage_AssertValid(message);
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&wireFormat);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_FromContentObjectPacketType)
+{
+ PARCBuffer *buffer = parcBuffer_Allocate(10);
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromContentObjectPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ assertTrue(ccnxTlvDictionary_IsContentObject((CCNxTlvDictionary *) message), "Wrong message type");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_FromControlPacketType)
+{
+ PARCBuffer *buffer = parcBuffer_Allocate(10);
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromControlPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ assertTrue(ccnxTlvDictionary_IsControl((CCNxTlvDictionary *) message), "Wrong message type");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_FromInterestPacketType)
+{
+ PARCBuffer *buffer = parcBuffer_Allocate(10);
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromInterestPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ assertTrue(ccnxTlvDictionary_IsInterest((CCNxTlvDictionary *) message), "Wrong message type");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_Create)
+{
+ PARCBuffer *wireFormat = parcBuffer_Wrap(v1_interest_nameA, sizeof(v1_interest_nameA), 0, sizeof(v1_interest_nameA));
+
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_Create(wireFormat);
+ assertNotNull(message, "Got null CCNxWireFormatMessage, after attempting to create with buffer");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&wireFormat);
+}
+
+/***
+ *** allocator(), deallocator(), createNetworkBufferIoVec() taken from test_ccnx_WireFormatFacadeV1.c
+ ***/
+
+/*
+ * Small size allocator for creating a network buffer
+ */
+static size_t
+_allocator(void *userarg, size_t bytes, void **output)
+{
+ const size_t allocationSize = *(size_t *) userarg;
+ void *allocated = parcMemory_Allocate(allocationSize);
+ *output = allocated;
+ return allocationSize;
+}
+
+/*
+ * deallocator for network buffer
+ */
+static void
+_deallocator(void *userarg, void **memoryPtr)
+{
+ parcMemory_Deallocate(memoryPtr);
+}
+static const CCNxCodecNetworkBufferMemoryBlockFunctions memory = { .allocator = _allocator, .deallocator = _deallocator };
+
+/*
+ * Create a network buffer that looks like this. The actual number of iovecs might
+ * be a little different, but the digest area will span several iovec.
+ *
+ * +-----------+-----------+-----------+-----------+-----------+
+ * iov[0] iov[1] iov[2] iov[3]
+ * +-----------+-----------+-----------+-----------+-----------+
+ * ^ ^
+ * | |
+ * start end
+ */
+static CCNxCodecNetworkBufferIoVec *
+_createNetworkBufferIoVec(size_t allocationSize, size_t padlen, uint8_t pad[padlen], size_t datalen, uint8_t data[datalen])
+{
+ CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_Create(&memory, &allocationSize);
+ // build the network buffer
+ ccnxCodecNetworkBuffer_PutArray(netbuff, padlen, pad);
+ ccnxCodecNetworkBuffer_PutArray(netbuff, datalen, data);
+ ccnxCodecNetworkBuffer_PutArray(netbuff, padlen, pad);
+
+ CCNxCodecNetworkBufferIoVec *vec = ccnxCodecNetworkBuffer_CreateIoVec(netbuff);
+ ccnxCodecNetworkBuffer_Release(&netbuff);
+ return vec;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_FromInterestPacketTypeIoVec)
+{
+ uint8_t data[64];
+
+ uint8_t pad[32];
+ CCNxCodecNetworkBufferIoVec *vec = _createNetworkBufferIoVec(512, 32, pad, 64, data);
+
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromInterestPacketTypeIoVec(CCNxTlvDictionary_SchemaVersion_V1, vec);
+
+ assertNotNull(message, "Got null CCNxWireFormatMessage");
+ assertTrue(ccnxTlvDictionary_IsInterest(message), "Wrong message type");
+ assertTrue(ccnxTlvDictionary_GetSchemaVersion(message) == CCNxTlvDictionary_SchemaVersion_V1,
+ "Wrong schema, got %d expected %d",
+ ccnxTlvDictionary_GetSchemaVersion(message), CCNxTlvDictionary_SchemaVersion_V1);
+
+ ccnxWireFormatMessage_Release(&message);
+ ccnxCodecNetworkBufferIoVec_Release(&vec);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_GetDictionary)
+{
+ PARCBuffer *buffer = parcBuffer_Allocate(10);
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromInterestPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ CCNxTlvDictionary *dictionary = ccnxWireFormatMessage_GetDictionary(message);
+ assertNotNull(dictionary, "Expected to retrieve the dictionary from the CCNxWireFormatMessage");
+ assertTrue(ccnxTlvDictionary_IsInterest(dictionary), "Wrong message type");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_PutGetIoVec)
+{
+ uint8_t *data = parcMemory_Allocate(64);
+ memset(data, 0, 64);
+
+ PARCBuffer *buffer = parcBuffer_Allocate(1);
+ CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_CreateFromArray(&ParcMemoryMemoryBlock, NULL, 64, data);
+ CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecNetworkBuffer_CreateIoVec(netbuff);
+
+ CCNxTlvDictionary *packet = ccnxCodecSchemaV1TlvDictionary_CreateInterest();
+ ccnxWireFormatMessage_PutIoVec((CCNxWireFormatMessage *) packet, iovec);
+
+ CCNxCodecNetworkBufferIoVec *test = ccnxWireFormatMessage_GetIoVec((CCNxWireFormatMessage *) packet);
+ assertTrue(test == iovec, "Failed to get iovec from dictionary, expected %p got %p", (void *) iovec, (void *) test);
+
+ ccnxTlvDictionary_Release(&packet);
+ parcBuffer_Release(&buffer);
+ ccnxCodecNetworkBufferIoVec_Release(&iovec);
+ ccnxCodecNetworkBuffer_Release(&netbuff);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_GetWireFormatBuffer)
+{
+ PARCBuffer *buffer = parcBuffer_Allocate(1);
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromInterestPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ PARCBuffer *test = ccnxWireFormatMessage_GetWireFormatBuffer(message);
+ assertTrue(test == buffer, "Retrieved unexpected buffer: got %p expected %p", (void *) test, (void *) buffer);
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_PutWireFormatBuffer)
+{
+ PARCBuffer *buffer = parcBuffer_Allocate(1);
+ CCNxTlvDictionary *packet = ccnxTlvDictionary_Create(20, 20);
+ ccnxTlvDictionary_SetMessageType_Interest(packet, CCNxTlvDictionary_SchemaVersion_V1);
+ bool success = ccnxWireFormatMessage_PutWireFormatBuffer(packet, buffer);
+
+ assertTrue(success, "Failed to put buffer in to dictionary");
+
+ PARCBuffer *test = ccnxWireFormatMessage_GetWireFormatBuffer(packet);
+ assertTrue(test == buffer, "Retrieved unexpected buffer: got %p expected %p", (void *) test, (void *) buffer);
+
+ ccnxTlvDictionary_Release(&packet);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_HashProtectedRegion)
+{
+ // >1234<
+ const char string[] = "Hello dev null\n";
+
+ PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));
+ size_t start = 5;
+ size_t length = 4;
+
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromContentObjectPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ ccnxWireFormatMessage_SetProtectedRegionStart(message, start);
+ ccnxWireFormatMessage_SetProtectedRegionLength(message, length);
+
+ PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256);
+ PARCCryptoHash *hash = ccnxWireFormatMessage_HashProtectedRegion(message, hasher);
+
+ // the correctness of the has is tested in _ccnxWireFormatFacadeV1_ComputeHash
+ assertNotNull(hash, "Got null hash from a good packet");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcCryptoHash_Release(&hash);
+ parcBuffer_Release(&buffer);
+ parcCryptoHasher_Release(&hasher);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_SetProtectedRegionLength)
+{
+ const char string[] = "Hello dev null\n";
+ PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));
+
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromContentObjectPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ size_t length = 5;
+ bool success = ccnxWireFormatMessage_SetProtectedRegionLength(message, length);
+ assertTrue(success, "Failed to put integer in to dictionary");
+
+ assertTrue(ccnxTlvDictionary_IsValueInteger(message, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_ProtectedLength), "ProtectedLength not set");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_SetProtectedRegionStart)
+{
+ const char string[] = "Hello dev null\n";
+ PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));
+
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromContentObjectPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ size_t start = 5;
+ bool success = ccnxWireFormatMessage_SetProtectedRegionStart(message, start);
+ assertTrue(success, "Failed to put integer in to dictionary");
+
+ assertTrue(ccnxTlvDictionary_IsValueInteger(message, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_ProtectedStart), "ProtectedStart not set");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&buffer);
+}
+
+static PARCBuffer *
+_iovecToParcBuffer(const CCNxCodecNetworkBufferIoVec *iovec)
+{
+ PARCBuffer *result = NULL;
+
+ size_t iovcnt = ccnxCodecNetworkBufferIoVec_GetCount((CCNxCodecNetworkBufferIoVec *) iovec);
+ const struct iovec *array = ccnxCodecNetworkBufferIoVec_GetArray((CCNxCodecNetworkBufferIoVec *) iovec);
+
+ size_t totalbytes = 0;
+ for (int i = 0; i < iovcnt; i++) {
+ totalbytes += array[i].iov_len;
+ }
+
+ result = parcBuffer_Allocate(totalbytes);
+ for (int i = 0; i < iovcnt; i++) {
+ parcBuffer_PutArray(result, array[i].iov_len, array[i].iov_base);
+ }
+
+ parcBuffer_Flip(result);
+
+
+ return result;
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_CreateContentObjectHash)
+{
+ // >1234<
+ const char string[] = "Hello dev null\n";
+
+ PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));
+
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromContentObjectPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ PARCCryptoHash *hash = ccnxWireFormatMessage_CreateContentObjectHash(message);
+ ccnxWireFormatMessage_Release(&message);
+ assertNull(hash, "Expect NULL for hash as it hasn't been encoded yet");
+
+ // We need to create a content object that is hashable
+ CCNxName *name = ccnxName_CreateFromCString("lci:/test/content");
+ CCNxContentObject *contentObject = ccnxContentObject_CreateWithNameAndPayload(name, buffer);
+ ccnxName_Release(&name);
+
+ // This next stuff is to force an encode/decode to setup hash extents
+ CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecTlvPacket_DictionaryEncode(contentObject, NULL);
+ ccnxContentObject_Release(&contentObject);
+ PARCBuffer *encodedMessage = _iovecToParcBuffer(iovec);
+ ccnxCodecNetworkBufferIoVec_Release(&iovec);
+ // Decode
+ message = ccnxWireFormatMessage_Create(encodedMessage);
+ CCNxTlvDictionary *dictionary = ccnxWireFormatMessage_GetDictionary(message);
+ bool success = ccnxCodecTlvPacket_BufferDecode(encodedMessage, dictionary);
+ assertTrue(success, "Failed to decode buffer");
+ parcBuffer_Release(&encodedMessage);
+
+ hash = ccnxWireFormatMessage_CreateContentObjectHash(message);
+
+ // the correctness of the hash is tested in _ccnxWireFormatFacadeV1_ComputeHash
+ assertNotNull(hash, "Got null hash from a good packet");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcCryptoHash_Release(&hash);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_WriteToFile)
+{
+ const char string[] = "Hello dev null\n";
+ PARCBuffer *buffer = parcBuffer_Wrap((void *) string, sizeof(string), 0, sizeof(string));
+ CCNxWireFormatMessage *message = ccnxWireFormatMessage_FromInterestPacketType(CCNxTlvDictionary_SchemaVersion_V1, buffer);
+
+ ccnxWireFormatMessage_WriteToFile(message, "/dev/null");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&buffer);
+}
+
+LONGBOW_TEST_CASE(Global, ccnxWireFormatMessage_SetHopLimit)
+{
+ uint8_t *data = parcMemory_Allocate(64);
+ memset(data, 0, 64);
+
+ PARCBuffer *buffer = parcBuffer_Allocate(1);
+ CCNxCodecNetworkBuffer *netbuff = ccnxCodecNetworkBuffer_CreateFromArray(&ParcMemoryMemoryBlock, NULL, 64, data);
+ CCNxCodecNetworkBufferIoVec *iovec = ccnxCodecNetworkBuffer_CreateIoVec(netbuff);
+
+ CCNxTlvDictionary *packet = ccnxCodecSchemaV1TlvDictionary_CreateInterest();
+ ccnxWireFormatMessage_PutIoVec((CCNxWireFormatMessage *) packet, iovec);
+
+ ccnxWireFormatMessage_SetHopLimit(packet, 10);
+
+ CCNxCodecNetworkBufferIoVec *test = ccnxWireFormatMessage_GetIoVec((CCNxWireFormatMessage *) packet);
+ assertTrue(test == iovec, "Failed to get iovec from dictionary, expected %p got %p", (void *) iovec, (void *) test);
+
+ ccnxTlvDictionary_Release(&packet);
+ parcBuffer_Release(&buffer);
+ ccnxCodecNetworkBufferIoVec_Release(&iovec);
+ ccnxCodecNetworkBuffer_Release(&netbuff);
+}
+LONGBOW_TEST_FIXTURE(Static)
+{
+ LONGBOW_RUN_TEST_CASE(Static, _getImplForSchema);
+ LONGBOW_RUN_TEST_CASE(Static, _ccnxWireFormatMessage_CreateWithImpl);
+}
+
+LONGBOW_TEST_FIXTURE_SETUP(Static)
+{
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_FIXTURE_TEARDOWN(Static)
+{
+ uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO);
+ if (outstandingAllocations != 0) {
+ printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations);
+ return LONGBOW_STATUS_MEMORYLEAK;
+ }
+ return LONGBOW_STATUS_SUCCEEDED;
+}
+
+LONGBOW_TEST_CASE(Static, _ccnxWireFormatMessage_CreateWithImpl)
+{
+ PARCBuffer *wireFormatV1 = parcBuffer_Wrap(v1_interest_nameA, sizeof(v1_interest_nameA), 0, sizeof(v1_interest_nameA));
+
+ CCNxWireFormatMessage *message = _ccnxWireFormatMessage_CreateWithImpl(&CCNxWireFormatFacadeV1_Implementation, wireFormatV1);
+ assertNotNull(message, "Expected to create a V1 CCNxWireFormatMessage");
+
+ ccnxWireFormatMessage_Release(&message);
+ parcBuffer_Release(&wireFormatV1);
+}
+
+LONGBOW_TEST_CASE(Static, _getImplForSchema)
+{
+ CCNxWireFormatMessageInterface *impl = _getImplForSchema(CCNxTlvDictionary_SchemaVersion_V1);
+ assertTrue(impl = &CCNxWireFormatFacadeV1_Implementation, "Expected to see CCNxWireFormatFacadeV1_Implementation");
+}
+
+int
+main(int argc, char *argv[])
+{
+ LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(ccnx_WireFormatMessage);
+ int exitStatus = longBowMain(argc, argv, testRunner, NULL);
+ longBowTestRunner_Destroy(&testRunner);
+ exit(exitStatus);
+}