Packages/MoonriseKit/Tests/ObservingLogTests/ProgramsTests.swift
105 lines · 4521 bytes
6 symbols in this file
1import Foundation
2import Testing
3@testable import ObservingLog
4
5@Test func designations() {
6 #expect(CatalogResolver.designation("M31") == "M31")
7 #expect(CatalogResolver.designation("M 31") == "M31")
8 #expect(CatalogResolver.designation(" messier 31 ") == "M31")
9 #expect(CatalogResolver.designation("M031") == "M31")
10 #expect(CatalogResolver.designation("NGC 6205") == "NGC6205")
11 #expect(CatalogResolver.designation("ic434") == "IC434")
12 #expect(CatalogResolver.designation("Saturn") == nil)
13 #expect(CatalogResolver.designation("M31 and M32") == nil)
14}
15
16@Test func messierNamesResolve() {
17 let r = CatalogResolver.messier
18 for name in ["M31", "M 31", "Messier 31", "Andromeda Galaxy", "andromeda galaxy"] {
19 #expect(r.id(for: name) == "M31", "\(name)")
20 }
21 #expect(r.id(for: "Ptolemy’s Cluster") == "M7")
22 #expect(r.id(for: "Winnecke 4") == "M40")
23 #expect(r.id(for: "M102") == "M102")
24 #expect(r.id(for: "Identity disputed") == nil)
25 #expect(r.id(for: "Saturn") == nil)
26}
27
28@Test func messierProgramHasAll110() throws {
29 let p = ObservingProgram.messier
30 #expect(p.objects.map(\.id) == (1...110).map { "M\($0)" })
31 let m31 = try #require(p.objects.first { $0.id == "M31" })
32 #expect(m31.aliases == ["Andromeda Galaxy"])
33 #expect(m31.ra != nil && m31.dec != nil)
34 // M102 has no position: OpenNGC lists it as a duplicate of M101 (see scripts/make-messier.py).
35 let m102 = try #require(p.objects.first { $0.id == "M102" })
36 #expect(m102.ra == nil && m102.dec == nil && m102.aliases.isEmpty)
37 #expect(p.objects.filter { $0.ra == nil }.count == 1)
38}
39
40@Test func programFromOrg() throws {
41 let text = """
42 #+TITLE: Autumn clusters
43 Open clusters for a small refractor.
44
45 * Double Cluster
46 :PROPERTIES:
47 :CATALOG: NGC869 NGC884
48 :RA: 34.75
49 :DEC: 57.13
50 :END:
51 Two clusters in one field.
52 ** Notes
53 * M 45
54 * Pleiades
55 * Stock 2
56 * Kemble's Cascade
57 """
58 let p = ObservingProgram(org: text, id: "autumn-clusters")
59 #expect(p.title == "Autumn clusters")
60 #expect(p.objects.map(\.id) == ["NGC869", "M45", "M45", "STOCK2", "kemble's cascade"])
61 #expect(p.objects.map(\.name) == ["Double Cluster", "M 45", "Pleiades", "Stock 2", "Kemble's Cascade"])
62 #expect(p.objects[0].ra == 34.75 && p.objects[0].dec == 57.13)
63 #expect(p.objects[0].aliases == ["Double Cluster"])
64 // Messier objects take their position from the bundled catalogue.
65 #expect(p.objects[1].ra == ObservingProgram.messier.objects[44].ra)
66 #expect(p.objects[3].ra == nil)
67
68 #expect(ObservingProgram(org: "* M13\n", id: "globulars").title == "globulars")
69
70 let r = CatalogResolver(programs: [.messier, p])
71 #expect(r.id(for: "double cluster") == "NGC869")
72 #expect(r.id(for: "Andromeda Galaxy") == "M31")
73}
74
75@Test func programsFolder() throws {
76 let dir = FileManager.default.temporaryDirectory.appending(path: "obs-\(UUID().uuidString)")
77 defer { try? FileManager.default.removeItem(at: dir) }
78 let log = ObservingLog(folder: dir)
79 #expect(log.programs().map(\.id) == ["messier"])
80 try FileManager.default.createDirectory(at: log.programsFolder, withIntermediateDirectories: true)
81 try "#+TITLE: Globulars\n* M13\n* M92\n".write(to: log.programsFolder.appending(path: "globulars.org"), atomically: true, encoding: .utf8)
82 try "notes".write(to: log.programsFolder.appending(path: "readme.txt"), atomically: true, encoding: .utf8)
83 #expect(log.programs().map(\.title) == ["Messier", "Globulars"])
84 // Program files are not log entries.
85 #expect(log.all().isEmpty)
86}
87
88@Test func progressCountsEachObjectOnce() throws {
89 let resolver = CatalogResolver.messier
90 let early = when.addingTimeInterval(-86_400)
91 let log = [
92 Observation(object: "Andromeda Galaxy", date: when, place: ""),
93 Observation(object: "M 31", date: early, place: ""),
94 Observation(object: "Dust lanes", date: when, place: "", catalog: ["M32"]),
95 Observation(object: "Saturn", date: when, place: ""),
96 Observation(object: "Kemble's Cascade", date: when, place: ""),
97 ]
98 let progress = ProgramProgress(program: .messier, log: log, resolver: resolver)
99 #expect(progress.count == 2)
100 #expect(progress.first["M31"]?.date == early)
101 #expect(progress.first["M32"] != nil)
102
103 let mine = ObservingProgram(org: "* Kemble’s Cascade\n* M31\n", id: "mine")
104 #expect(ProgramProgress(program: mine, log: log, resolver: resolver).count == 2)
105}