Update AppleScript to differentiate between WebFeeds and Feeds

This commit is contained in:
Maurice Parker 2019-11-15 15:46:43 -06:00
parent 5283d2efbe
commit d3e5985258
15 changed files with 117 additions and 134 deletions

View File

@ -36,7 +36,7 @@ set totalFeeds to 0
tell application "NetNewsWire"
set allAccounts to every account
repeat with nthAccount in allAccounts
set allFeeds to every feed of nthAccount
set allFeeds to every webFeed of nthAccount
repeat with nthFeed in allFeeds
set feedname to name of nthFeed
set articleCount to count (get every article of nthFeed)

View File

@ -38,7 +38,7 @@ set safariWindow to missing value
tell application "NetNewsWire"
set allAccounts to every account
repeat with nthAccount in allAccounts
set allFeeds to every feed of nthAccount
set allFeeds to every webFeed of nthAccount
repeat with nthFeed in allFeeds
set starredArticles to (get every article of nthFeed where starred is true)
repeat with nthArticle in starredArticles

View File

@ -60,8 +60,8 @@
<element type="account">
<cocoa key="accounts"/>
</element>
<element type="feed">
<cocoa key="feeds"/>
<element type="webFeed">
<cocoa key="webFeeds"/>
</element>
</class>
@ -88,30 +88,30 @@
<property name="active" code="Actv" type="boolean" access="rw" description="Whether or not the account is active">
<cocoa key="scriptingIsActive"/>
</property>
<property name="allFeeds" code="Feds" access="r" description="All feeds, including feeds inside folders">
<cocoa key="allFeeds"/>
<type type="feed" list="yes"/>
<property name="allWebFeeds" code="Feds" access="r" description="All feeds, including feeds inside folders">
<cocoa key="allWebFeeds"/>
<type type="webFeed" list="yes"/>
</property>
<property name="opml representation" code="OPML" type="text" access="r" description="OPML representation for the account">
<cocoa key="opmlRepresentation"/>
</property>
<element type="feed">
<cocoa key="feeds"/>
<element type="webFeed">
<cocoa key="webFeeds"/>
</element>
<element type="folder">
<cocoa key="folders"/>
</element>
</class>
<class name="feed" code="Feed" plural="feeds" description="An RSS feeds">
<cocoa class="ScriptableFeed"/>
<class name="webFeed" code="Feed" plural="webFeeds" description="An RSS feed">
<cocoa class="ScriptableWebFeed"/>
<property name="name" code="pnam" type="text" access="r" description="The name of the feed">
<cocoa key="name"/>
</property>
<property name="id" code="ID " type="text" access="r" description="The unique id of the account">
<property name="id" code="ID " type="text" access="r" description="The unique id of the feed">
<cocoa key="uniqueId"/>
</property>
<property name="url" code="URL " type="text" access="r" description="The type of the account">
<property name="url" code="URL " type="text" access="r" description="The type of the feed">
<cocoa key="url"/>
</property>
<property name="homepage url" code="HpUr" type="text" access="r" description="url for the feed homepage (optional)">
@ -164,8 +164,8 @@
<property name="opml representation" code="OPML" type="text" access="r" description="OPML representation for the folder">
<cocoa key="opmlRepresentation"/>
</property>
<element type="feed">
<cocoa key="feeds"/>
<element type="webFeed">
<cocoa key="webFeeds"/>
</element>
</class>

View File

@ -73,7 +73,7 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
account.removeFolder(scriptableFolder.folder) { result in
}
}
} else if let scriptableFeed = element as? ScriptableFeed {
} else if let scriptableFeed = element as? ScriptableWebFeed {
BatchUpdate.shared.perform {
var container: Container? = nil
if let scriptableFolder = scriptableFeed.container as? ScriptableFolder {
@ -94,23 +94,23 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
// MARK: --- Scriptable elements ---
@objc(feeds)
var feeds:NSArray {
return account.topLevelWebFeeds.map { ScriptableFeed($0, container:self) } as NSArray
@objc(webFeeds)
var webFeeds:NSArray {
return account.topLevelWebFeeds.map { ScriptableWebFeed($0, container:self) } as NSArray
}
@objc(valueInFeedsWithUniqueID:)
func valueInFeeds(withUniqueID id:String) -> ScriptableFeed? {
@objc(valueInWebFeedsWithUniqueID:)
func valueInWebFeeds(withUniqueID id:String) -> ScriptableWebFeed? {
let feeds = Array(account.topLevelWebFeeds)
guard let feed = feeds.first(where:{$0.webFeedID == id}) else { return nil }
return ScriptableFeed(feed, container:self)
return ScriptableWebFeed(feed, container:self)
}
@objc(valueInFeedsWithName:)
func valueInFeeds(withName name:String) -> ScriptableFeed? {
@objc(valueInWebFeedsWithName:)
func valueInWebFeeds(withName name:String) -> ScriptableWebFeed? {
let feeds = Array(account.topLevelWebFeeds)
guard let feed = feeds.first(where:{$0.name == name}) else { return nil }
return ScriptableFeed(feed, container:self)
return ScriptableWebFeed(feed, container:self)
}
@objc(folders)
@ -131,21 +131,21 @@ class ScriptableAccount: NSObject, UniqueIdScriptingObject, ScriptingObjectConta
// MARK: --- Scriptable properties ---
@objc(allFeeds)
var allFeeds: NSArray {
var feeds = [ScriptableFeed]()
for feed in account.topLevelWebFeeds {
feeds.append(ScriptableFeed(feed, container: self))
@objc(allWebFeeds)
var allWebFeeds: NSArray {
var webFeeds = [ScriptableWebFeed]()
for webFeed in account.topLevelWebFeeds {
webFeeds.append(ScriptableWebFeed(webFeed, container: self))
}
if let folders = account.folders {
for folder in folders {
let scriptableFolder = ScriptableFolder(folder, container: self)
for feed in folder.topLevelWebFeeds {
feeds.append(ScriptableFeed(feed, container: scriptableFolder))
for webFeed in folder.topLevelWebFeeds {
webFeeds.append(ScriptableWebFeed(webFeed, container: scriptableFolder))
}
}
}
return feeds as NSArray
return webFeeds as NSArray
}
@objc(opmlRepresentation)

View File

@ -59,8 +59,8 @@ extension AppDelegate : AppDelegateAppleEvents {
class NetNewsWireCreateElementCommand : NSCreateCommand {
override func performDefaultImplementation() -> Any? {
let classDescription = self.createClassDescription
if (classDescription.className == "feed") {
return ScriptableFeed.handleCreateElement(command:self)
if (classDescription.className == "webFeed") {
return ScriptableWebFeed.handleCreateElement(command:self)
} else if (classDescription.className == "folder") {
return ScriptableFolder.handleCreateElement(command:self)
}

View File

@ -51,7 +51,7 @@ class ScriptableFolder: NSObject, UniqueIdScriptingObject, ScriptingObjectContai
}
func deleteElement(_ element:ScriptingObject) {
if let scriptableFeed = element as? ScriptableFeed {
if let scriptableFeed = element as? ScriptableWebFeed {
BatchUpdate.shared.perform {
folder.account?.removeWebFeed(scriptableFeed.webFeed, from: folder) { result in }
}
@ -95,10 +95,10 @@ class ScriptableFolder: NSObject, UniqueIdScriptingObject, ScriptingObjectContai
// MARK: --- Scriptable elements ---
@objc(feeds)
var feeds:NSArray {
@objc(webFeeds)
var webFeeds:NSArray {
let feeds = Array(folder.topLevelWebFeeds)
return feeds.map { ScriptableFeed($0, container:self) } as NSArray
return feeds.map { ScriptableWebFeed($0, container:self) } as NSArray
}
// MARK: --- Scriptable properties ---

View File

@ -31,7 +31,7 @@ extension NSApplication : ScriptingObjectContainer {
var scriptableArticle: ScriptableArticle?
if let currentArticle = appDelegate.scriptingCurrentArticle {
if let feed = currentArticle.webFeed {
let scriptableFeed = ScriptableFeed(feed, container:self)
let scriptableFeed = ScriptableWebFeed(feed, container:self)
scriptableArticle = ScriptableArticle(currentArticle, container:scriptableFeed)
}
}
@ -43,7 +43,7 @@ extension NSApplication : ScriptingObjectContainer {
let articles = appDelegate.scriptingSelectedArticles
let scriptableArticles:[ScriptableArticle] = articles.compactMap { article in
if let feed = article.webFeed {
let scriptableFeed = ScriptableFeed(feed, container:self)
let scriptableFeed = ScriptableWebFeed(feed, container:self)
return ScriptableArticle(article, container:scriptableFeed)
} else {
return nil
@ -73,7 +73,7 @@ extension NSApplication : ScriptingObjectContainer {
for 'articles of feed "The Shape of Everything" of account "On My Mac"'
*/
func allFeeds() -> [WebFeed] {
func allWebFeeds() -> [WebFeed] {
let accounts = AccountManager.shared.activeAccounts
let emptyFeeds:[WebFeed] = []
return accounts.reduce(emptyFeeds) { (result, nthAccount) -> [WebFeed] in
@ -82,17 +82,17 @@ extension NSApplication : ScriptingObjectContainer {
}
}
@objc(feeds)
func feeds() -> NSArray {
let feeds = self.allFeeds()
return feeds.map { ScriptableFeed($0, container:self) } as NSArray
@objc(webFeeds)
func webFeeds() -> NSArray {
let webFeeds = self.allWebFeeds()
return webFeeds.map { ScriptableWebFeed($0, container:self) } as NSArray
}
@objc(valueInFeedsWithUniqueID:)
func valueInFeeds(withUniqueID id:String) -> ScriptableFeed? {
let feeds = self.allFeeds()
guard let feed = feeds.first(where:{$0.webFeedID == id}) else { return nil }
return ScriptableFeed(feed, container:self)
@objc(valueInWebFeedsWithUniqueID:)
func valueInWebFeeds(withUniqueID id:String) -> ScriptableWebFeed? {
let webFeeds = self.allWebFeeds()
guard let webFeed = webFeeds.first(where:{$0.webFeedID == id}) else { return nil }
return ScriptableWebFeed(webFeed, container:self)
}
}

View File

@ -11,14 +11,14 @@ import RSParser
import Account
import Articles
@objc(ScriptableFeed)
class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContainer {
@objc(ScriptableWebFeed)
class ScriptableWebFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContainer {
let webFeed:WebFeed
let container:ScriptingObjectContainer
init (_ feed:WebFeed, container:ScriptingObjectContainer) {
self.webFeed = feed
init (_ webFeed:WebFeed, container:ScriptingObjectContainer) {
self.webFeed = webFeed
self.container = container
}
@ -36,7 +36,7 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
// MARK: --- ScriptingObject protocol ---
var scriptingKey: String {
return "feeds"
return "webFeeds"
}
// MARK: --- UniqueIdScriptingObject protocol ---
@ -71,13 +71,13 @@ class ScriptableFeed: NSObject, UniqueIdScriptingObject, ScriptingObjectContaine
return url
}
class func scriptableFeed(_ feed:WebFeed, account:Account, folder:Folder?) -> ScriptableFeed {
class func scriptableFeed(_ feed:WebFeed, account:Account, folder:Folder?) -> ScriptableWebFeed {
let scriptableAccount = ScriptableAccount(account)
if let folder = folder {
let scriptableFolder = ScriptableFolder(folder, container:scriptableAccount)
return ScriptableFeed(feed, container:scriptableFolder)
return ScriptableWebFeed(feed, container:scriptableFolder)
} else {
return ScriptableFeed(feed, container:scriptableAccount)
return ScriptableWebFeed(feed, container:scriptableAccount)
}
}

View File

@ -384,7 +384,7 @@
65ED4037235DEF6C0081F399 /* FolderTreeControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97A11ED9F180007D329B /* FolderTreeControllerDelegate.swift */; };
65ED4038235DEF6C0081F399 /* RSImage-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */; };
65ED4039235DEF6C0081F399 /* SingleFaviconDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845A29081FC74B8E007B49E3 /* SingleFaviconDownloader.swift */; };
65ED403A235DEF6C0081F399 /* Feed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */; };
65ED403A235DEF6C0081F399 /* WebFeed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* WebFeed+Scriptability.swift */; };
65ED403B235DEF6C0081F399 /* AuthorAvatarDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E850851FCB60CE0072EA88 /* AuthorAvatarDownloader.swift */; };
65ED403C235DEF6C0081F399 /* SingleLineTextFieldSizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E185B2203B74E500F69BFA /* SingleLineTextFieldSizer.swift */; };
65ED403D235DEF6C0081F399 /* TimelineTableCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849A97741ED9EC04007D329B /* TimelineTableCellView.swift */; };
@ -622,7 +622,7 @@
D5E4CC54202C1361009B4FFC /* AppDelegate+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E4CC53202C1361009B4FFC /* AppDelegate+Scriptability.swift */; };
D5E4CC64202C1AC1009B4FFC /* MainWindowController+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E4CC63202C1AC1009B4FFC /* MainWindowController+Scriptability.swift */; };
D5F4EDB5200744A700B9E363 /* ScriptingObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */; };
D5F4EDB720074D6500B9E363 /* Feed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */; };
D5F4EDB720074D6500B9E363 /* WebFeed+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB620074D6500B9E363 /* WebFeed+Scriptability.swift */; };
D5F4EDB920074D7C00B9E363 /* Folder+Scriptability.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */; };
DD82AB0A231003F6002269DF /* SharingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD82AB09231003F6002269DF /* SharingTests.swift */; };
FF3ABF13232599810074C542 /* ArticleSorterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF09232599450074C542 /* ArticleSorterTests.swift */; };
@ -1549,7 +1549,7 @@
D5E4CC53202C1361009B4FFC /* AppDelegate+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Scriptability.swift"; sourceTree = "<group>"; };
D5E4CC63202C1AC1009B4FFC /* MainWindowController+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainWindowController+Scriptability.swift"; sourceTree = "<group>"; };
D5F4EDB4200744A700B9E363 /* ScriptingObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptingObject.swift; sourceTree = "<group>"; };
D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Feed+Scriptability.swift"; sourceTree = "<group>"; };
D5F4EDB620074D6500B9E363 /* WebFeed+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WebFeed+Scriptability.swift"; sourceTree = "<group>"; };
D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Folder+Scriptability.swift"; sourceTree = "<group>"; };
DD82AB09231003F6002269DF /* SharingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharingTests.swift; sourceTree = "<group>"; };
FF3ABF09232599450074C542 /* ArticleSorterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorterTests.swift; sourceTree = "<group>"; };
@ -2689,7 +2689,7 @@
D5E4CC53202C1361009B4FFC /* AppDelegate+Scriptability.swift */,
D553737C20186C1F006D8857 /* Article+Scriptability.swift */,
D5A2678B20130ECF00A8D3C0 /* Author+Scriptability.swift */,
D5F4EDB620074D6500B9E363 /* Feed+Scriptability.swift */,
D5F4EDB620074D6500B9E363 /* WebFeed+Scriptability.swift */,
D5F4EDB820074D7C00B9E363 /* Folder+Scriptability.swift */,
D5E4CC63202C1AC1009B4FFC /* MainWindowController+Scriptability.swift */,
D5907D7E2004AC00005947E5 /* NSApplication+Scriptability.swift */,
@ -3848,7 +3848,7 @@
65ED4037235DEF6C0081F399 /* FolderTreeControllerDelegate.swift in Sources */,
65ED4038235DEF6C0081F399 /* RSImage-Extensions.swift in Sources */,
65ED4039235DEF6C0081F399 /* SingleFaviconDownloader.swift in Sources */,
65ED403A235DEF6C0081F399 /* Feed+Scriptability.swift in Sources */,
65ED403A235DEF6C0081F399 /* WebFeed+Scriptability.swift in Sources */,
65ED403B235DEF6C0081F399 /* AuthorAvatarDownloader.swift in Sources */,
65ED403C235DEF6C0081F399 /* SingleLineTextFieldSizer.swift in Sources */,
65ED403D235DEF6C0081F399 /* TimelineTableCellView.swift in Sources */,
@ -4137,7 +4137,7 @@
849A97A31ED9F180007D329B /* FolderTreeControllerDelegate.swift in Sources */,
51126DA4225FDE2F00722696 /* RSImage-Extensions.swift in Sources */,
845A29091FC74B8E007B49E3 /* SingleFaviconDownloader.swift in Sources */,
D5F4EDB720074D6500B9E363 /* Feed+Scriptability.swift in Sources */,
D5F4EDB720074D6500B9E363 /* WebFeed+Scriptability.swift in Sources */,
84E850861FCB60CE0072EA88 /* AuthorAvatarDownloader.swift in Sources */,
84E185B3203B74E500F69BFA /* SingleLineTextFieldSizer.swift in Sources */,
849A977A1ED9EC04007D329B /* TimelineTableCellView.swift in Sources */,

View File

@ -19,10 +19,10 @@ class ArticleSorterTests: XCTestCase {
func testSortByDateAscending() {
let now = Date()
let article1 = TestArticle(sortableName: "Susie's Feed", sortableDate: now.addingTimeInterval(-60.0), sortableArticleID: "1", sortableFeedID: "4")
let article2 = TestArticle(sortableName: "Phil's Feed", sortableDate: now.addingTimeInterval(60.0), sortableArticleID: "2", sortableFeedID: "6")
let article3 = TestArticle(sortableName: "Phil's Feed", sortableDate: now.addingTimeInterval(120.0), sortableArticleID: "3", sortableFeedID: "6")
let article4 = TestArticle(sortableName: "Susie's Feed", sortableDate: now.addingTimeInterval(-120.0), sortableArticleID: "4", sortableFeedID: "5")
let article1 = TestArticle(sortableName: "Susie's Feed", sortableDate: now.addingTimeInterval(-60.0), sortableArticleID: "1", sortableWebFeedID: "4")
let article2 = TestArticle(sortableName: "Phil's Feed", sortableDate: now.addingTimeInterval(60.0), sortableArticleID: "2", sortableWebFeedID: "6")
let article3 = TestArticle(sortableName: "Phil's Feed", sortableDate: now.addingTimeInterval(120.0), sortableArticleID: "3", sortableWebFeedID: "6")
let article4 = TestArticle(sortableName: "Susie's Feed", sortableDate: now.addingTimeInterval(-120.0), sortableArticleID: "4", sortableWebFeedID: "5")
let articles = [article1, article2, article3, article4]
let sortedArticles = ArticleSorter.sortedByDate(articles: articles,
@ -40,11 +40,11 @@ class ArticleSorterTests: XCTestCase {
let now = Date()
// Articles with the same date should end up being sorted by their article ID
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "1", sortableFeedID: "1")
let article2 = TestArticle(sortableName: "Matt's Feed", sortableDate: now, sortableArticleID: "2", sortableFeedID: "2")
let article3 = TestArticle(sortableName: "Sally's Feed", sortableDate: now, sortableArticleID: "3", sortableFeedID: "3")
let article4 = TestArticle(sortableName: "Susie's Feed", sortableDate: Date(timeInterval: -60.0, since: now), sortableArticleID: "4", sortableFeedID: "4")
let article5 = TestArticle(sortableName: "Paul's Feed", sortableDate: Date(timeInterval: -120.0, since: now), sortableArticleID: "5", sortableFeedID: "5")
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "1", sortableWebFeedID: "1")
let article2 = TestArticle(sortableName: "Matt's Feed", sortableDate: now, sortableArticleID: "2", sortableWebFeedID: "2")
let article3 = TestArticle(sortableName: "Sally's Feed", sortableDate: now, sortableArticleID: "3", sortableWebFeedID: "3")
let article4 = TestArticle(sortableName: "Susie's Feed", sortableDate: Date(timeInterval: -60.0, since: now), sortableArticleID: "4", sortableWebFeedID: "4")
let article5 = TestArticle(sortableName: "Paul's Feed", sortableDate: Date(timeInterval: -120.0, since: now), sortableArticleID: "5", sortableWebFeedID: "5")
let articles = [article1, article2, article3, article4, article5]
let sortedArticles = ArticleSorter.sortedByDate(articles: articles,
@ -62,15 +62,15 @@ class ArticleSorterTests: XCTestCase {
func testSortByDateAscendingWithGroupByFeed() {
let now = Date()
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: Date(timeInterval: -100.0, since: now), sortableArticleID: "1", sortableFeedID: "1")
let article2 = TestArticle(sortableName: "Jenny's Feed", sortableDate: now, sortableArticleID: "1", sortableFeedID: "2")
let article3 = TestArticle(sortableName: "Jenny's Feed", sortableDate: Date(timeInterval: -10.0, since: now), sortableArticleID: "2", sortableFeedID: "2")
let article4 = TestArticle(sortableName: "Gordy's Blog", sortableDate: Date(timeInterval: -1000.0, since: now), sortableArticleID: "1", sortableFeedID: "3")
let article5 = TestArticle(sortableName: "Gordy's Blog", sortableDate: Date(timeInterval: -10.0, since: now), sortableArticleID: "2", sortableFeedID: "3")
let article6 = TestArticle(sortableName: "Jenny's Feed", sortableDate: Date(timeInterval: 10.0, since: now), sortableArticleID: "3", sortableFeedID: "2")
let article7 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "2", sortableFeedID: "1")
let article8 = TestArticle(sortableName: "Zippy's Feed", sortableDate: now, sortableArticleID: "1", sortableFeedID: "0")
let article9 = TestArticle(sortableName: "Zippy's Feed", sortableDate: now, sortableArticleID: "2", sortableFeedID: "0")
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: Date(timeInterval: -100.0, since: now), sortableArticleID: "1", sortableWebFeedID: "1")
let article2 = TestArticle(sortableName: "Jenny's Feed", sortableDate: now, sortableArticleID: "1", sortableWebFeedID: "2")
let article3 = TestArticle(sortableName: "Jenny's Feed", sortableDate: Date(timeInterval: -10.0, since: now), sortableArticleID: "2", sortableWebFeedID: "2")
let article4 = TestArticle(sortableName: "Gordy's Blog", sortableDate: Date(timeInterval: -1000.0, since: now), sortableArticleID: "1", sortableWebFeedID: "3")
let article5 = TestArticle(sortableName: "Gordy's Blog", sortableDate: Date(timeInterval: -10.0, since: now), sortableArticleID: "2", sortableWebFeedID: "3")
let article6 = TestArticle(sortableName: "Jenny's Feed", sortableDate: Date(timeInterval: 10.0, since: now), sortableArticleID: "3", sortableWebFeedID: "2")
let article7 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "2", sortableWebFeedID: "1")
let article8 = TestArticle(sortableName: "Zippy's Feed", sortableDate: now, sortableArticleID: "1", sortableWebFeedID: "0")
let article9 = TestArticle(sortableName: "Zippy's Feed", sortableDate: now, sortableArticleID: "2", sortableWebFeedID: "0")
let articles = [article1, article2, article3, article4, article5, article6, article7, article8, article9]
let sortedArticles = ArticleSorter.sortedByDate(articles: articles, sortDirection: .orderedAscending, groupByFeed: true)
@ -97,10 +97,10 @@ class ArticleSorterTests: XCTestCase {
func testSortByDateDescending() {
let now = Date()
let article1 = TestArticle(sortableName: "Susie's Feed", sortableDate: now.addingTimeInterval(-60.0), sortableArticleID: "1", sortableFeedID: "4")
let article2 = TestArticle(sortableName: "Phil's Feed", sortableDate: now.addingTimeInterval(60.0), sortableArticleID: "2", sortableFeedID: "6")
let article3 = TestArticle(sortableName: "Phil's Feed", sortableDate: now.addingTimeInterval(120.0), sortableArticleID: "3", sortableFeedID: "6")
let article4 = TestArticle(sortableName: "Susie's Feed", sortableDate: now.addingTimeInterval(-120.0), sortableArticleID: "4", sortableFeedID: "5")
let article1 = TestArticle(sortableName: "Susie's Feed", sortableDate: now.addingTimeInterval(-60.0), sortableArticleID: "1", sortableWebFeedID: "4")
let article2 = TestArticle(sortableName: "Phil's Feed", sortableDate: now.addingTimeInterval(60.0), sortableArticleID: "2", sortableWebFeedID: "6")
let article3 = TestArticle(sortableName: "Phil's Feed", sortableDate: now.addingTimeInterval(120.0), sortableArticleID: "3", sortableWebFeedID: "6")
let article4 = TestArticle(sortableName: "Susie's Feed", sortableDate: now.addingTimeInterval(-120.0), sortableArticleID: "4", sortableWebFeedID: "5")
let articles = [article1, article2, article3, article4]
let sortedArticles = ArticleSorter.sortedByDate(articles: articles,
@ -118,11 +118,11 @@ class ArticleSorterTests: XCTestCase {
let now = Date()
// Articles with the same date should end up being sorted by their article ID
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "1", sortableFeedID: "1")
let article2 = TestArticle(sortableName: "Matt's Feed", sortableDate: now, sortableArticleID: "2", sortableFeedID: "2")
let article3 = TestArticle(sortableName: "Sally's Feed", sortableDate: now, sortableArticleID: "3", sortableFeedID: "3")
let article4 = TestArticle(sortableName: "Susie's Feed", sortableDate: Date(timeInterval: -60.0, since: now), sortableArticleID: "4", sortableFeedID: "4")
let article5 = TestArticle(sortableName: "Paul's Feed", sortableDate: Date(timeInterval: -120.0, since: now), sortableArticleID: "5", sortableFeedID: "5")
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "1", sortableWebFeedID: "1")
let article2 = TestArticle(sortableName: "Matt's Feed", sortableDate: now, sortableArticleID: "2", sortableWebFeedID: "2")
let article3 = TestArticle(sortableName: "Sally's Feed", sortableDate: now, sortableArticleID: "3", sortableWebFeedID: "3")
let article4 = TestArticle(sortableName: "Susie's Feed", sortableDate: Date(timeInterval: -60.0, since: now), sortableArticleID: "4", sortableWebFeedID: "4")
let article5 = TestArticle(sortableName: "Paul's Feed", sortableDate: Date(timeInterval: -120.0, since: now), sortableArticleID: "5", sortableWebFeedID: "5")
let articles = [article1, article2, article3, article4, article5]
let sortedArticles = ArticleSorter.sortedByDate(articles: articles,
@ -140,15 +140,15 @@ class ArticleSorterTests: XCTestCase {
func testSortByDateDescendingWithGroupByFeed() {
let now = Date()
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: Date(timeInterval: -100.0, since: now), sortableArticleID: "1", sortableFeedID: "1")
let article2 = TestArticle(sortableName: "Jenny's Feed", sortableDate: now, sortableArticleID: "1", sortableFeedID: "2")
let article3 = TestArticle(sortableName: "Jenny's Feed", sortableDate: Date(timeInterval: -10.0, since: now), sortableArticleID: "2", sortableFeedID: "2")
let article4 = TestArticle(sortableName: "Gordy's Blog", sortableDate: Date(timeInterval: -1000.0, since: now), sortableArticleID: "1", sortableFeedID: "3")
let article5 = TestArticle(sortableName: "Gordy's Blog", sortableDate: Date(timeInterval: -10.0, since: now), sortableArticleID: "2", sortableFeedID: "3")
let article6 = TestArticle(sortableName: "Jenny's Feed", sortableDate: Date(timeInterval: 10.0, since: now), sortableArticleID: "3", sortableFeedID: "2")
let article7 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "2", sortableFeedID: "1")
let article8 = TestArticle(sortableName: "Zippy's Feed", sortableDate: now, sortableArticleID: "1", sortableFeedID: "0")
let article9 = TestArticle(sortableName: "Zippy's Feed", sortableDate: now, sortableArticleID: "2", sortableFeedID: "0")
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: Date(timeInterval: -100.0, since: now), sortableArticleID: "1", sortableWebFeedID: "1")
let article2 = TestArticle(sortableName: "Jenny's Feed", sortableDate: now, sortableArticleID: "1", sortableWebFeedID: "2")
let article3 = TestArticle(sortableName: "Jenny's Feed", sortableDate: Date(timeInterval: -10.0, since: now), sortableArticleID: "2", sortableWebFeedID: "2")
let article4 = TestArticle(sortableName: "Gordy's Blog", sortableDate: Date(timeInterval: -1000.0, since: now), sortableArticleID: "1", sortableWebFeedID: "3")
let article5 = TestArticle(sortableName: "Gordy's Blog", sortableDate: Date(timeInterval: -10.0, since: now), sortableArticleID: "2", sortableWebFeedID: "3")
let article6 = TestArticle(sortableName: "Jenny's Feed", sortableDate: Date(timeInterval: 10.0, since: now), sortableArticleID: "3", sortableWebFeedID: "2")
let article7 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "2", sortableWebFeedID: "1")
let article8 = TestArticle(sortableName: "Zippy's Feed", sortableDate: now, sortableArticleID: "1", sortableWebFeedID: "0")
let article9 = TestArticle(sortableName: "Zippy's Feed", sortableDate: now, sortableArticleID: "2", sortableWebFeedID: "0")
let articles = [article1, article2, article3, article4, article5, article6, article7, article8, article9]
let sortedArticles = ArticleSorter.sortedByDate(articles: articles, sortDirection: .orderedDescending, groupByFeed: true)
@ -175,11 +175,11 @@ class ArticleSorterTests: XCTestCase {
func testGroupByFeedWithCaseInsensitiveFeedNames() {
let now = Date()
let article1 = TestArticle(sortableName: "phil's feed", sortableDate: now, sortableArticleID: "1", sortableFeedID: "1")
let article2 = TestArticle(sortableName: "PhIl's FEed", sortableDate: now, sortableArticleID: "2", sortableFeedID: "1")
let article3 = TestArticle(sortableName: "APPLE's feed", sortableDate: now, sortableArticleID: "3", sortableFeedID: "2")
let article4 = TestArticle(sortableName: "PHIL'S FEED", sortableDate: now, sortableArticleID: "4", sortableFeedID: "1")
let article5 = TestArticle(sortableName: "apple's feed", sortableDate: now, sortableArticleID: "5", sortableFeedID: "2")
let article1 = TestArticle(sortableName: "phil's feed", sortableDate: now, sortableArticleID: "1", sortableWebFeedID: "1")
let article2 = TestArticle(sortableName: "PhIl's FEed", sortableDate: now, sortableArticleID: "2", sortableWebFeedID: "1")
let article3 = TestArticle(sortableName: "APPLE's feed", sortableDate: now, sortableArticleID: "3", sortableWebFeedID: "2")
let article4 = TestArticle(sortableName: "PHIL'S FEED", sortableDate: now, sortableArticleID: "4", sortableWebFeedID: "1")
let article5 = TestArticle(sortableName: "apple's feed", sortableDate: now, sortableArticleID: "5", sortableWebFeedID: "2")
let articles = [article1, article2, article3, article4, article5]
let sortedArticles = ArticleSorter.sortedByDate(articles: articles,
@ -201,11 +201,11 @@ class ArticleSorterTests: XCTestCase {
let now = Date()
// Articles with the same feed name should be sorted by feed ID
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "1", sortableFeedID: "2")
let article2 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "2", sortableFeedID: "2")
let article3 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "3", sortableFeedID: "1")
let article4 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "4", sortableFeedID: "2")
let article5 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "5", sortableFeedID: "1")
let article1 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "1", sortableWebFeedID: "2")
let article2 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "2", sortableWebFeedID: "2")
let article3 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "3", sortableWebFeedID: "1")
let article4 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "4", sortableWebFeedID: "2")
let article5 = TestArticle(sortableName: "Phil's Feed", sortableDate: now, sortableArticleID: "5", sortableWebFeedID: "1")
let articles = [article1, article2, article3, article4, article5]
let sortedArticles = ArticleSorter.sortedByDate(articles: articles,
@ -226,7 +226,7 @@ private struct TestArticle: SortableArticle, Equatable {
let sortableName: String
let sortableDate: Date
let sortableArticleID: String
let sortableFeedID: String
let sortableWebFeedID: String
}
private extension Array where Element == TestArticle {

View File

@ -1,7 +1,7 @@
-- this script just tests that no error was generated from the script
try
tell application "NetNewsWire"
exists feed 1 of account 1
exists webFeed 1 of account 1
end tell
on error message
return {test_result:false, script_result:message}

View File

@ -1,7 +1,7 @@
-- this script just tests that no error was generated from the script
try
tell application "NetNewsWire"
opml representation of feed 1 of account 1
opml representation of webFeed 1 of account 1
end tell
on error message
return {test_result:false, script_result:message}

View File

@ -1,7 +1,7 @@
-- this script just tests that no error was generated from the script
try
tell application "NetNewsWire"
{name, url} of every feed of every account
{name, url} of every webFeed of every account
end tell
on error message
return {test_result:false, script_result:message}

View File

@ -2,7 +2,7 @@
-- and that the returned list is greater than 0
try
tell application "NetNewsWire"
set namesResult to name of every author of every feed of every account
set namesResult to name of every author of every webFeed of every account
end tell
set test_result to ((count items of namesResult) > 0)
on error message

View File

@ -39,24 +39,7 @@ class SharingTests: XCTestCase {
private func article(titled title: String) -> Article {
let articleId = randomId()
return Article(
accountID: randomId(),
articleID: articleId,
feedID: randomId(),
uniqueID: randomId(),
title: title,
contentHTML: nil,
contentText: nil,
url: nil,
externalURL: nil,
summary: nil,
imageURL: nil,
bannerImageURL: nil,
datePublished: nil,
dateModified: nil,
authors: nil,
attachments: nil,
status: ArticleStatus(articleID: articleId, read: true, dateArrived: Date())
return Article(accountID: randomId(), articleID: articleId, webFeedID: randomId(), uniqueID: randomId(), title: title, contentHTML: nil, contentText: nil, url: nil, externalURL: nil, summary: nil, imageURL: nil, bannerImageURL: nil, datePublished: nil, dateModified: nil, authors: nil, attachments: nil, status: ArticleStatus(articleID: articleId, read: true, dateArrived: Date())
)
}