marsdate 1.1.7 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/test/test.rb CHANGED
@@ -1,377 +1,369 @@
1
- require './lib/marsdate'
1
+ #!/usr/bin/env ruby
2
+ # MarsDateTime constructors on the official MSD timeline.
3
+ # Run: ruby test/test.rb
2
4
 
3
- require 'rubygems'
4
5
  require 'minitest/autorun'
5
- require 'shoulda'
6
- require 'pp'
6
+ require_relative '../lib/marsdate'
7
+ require 'date'
8
+
9
+ class MarsDateTest < Minitest::Test
10
+ def test_civil_ymd_round_trips
11
+ assert_equal [1, 1, 1, 0, 0, 0], MarsDateTime.new(1, 1, 1).ymshms
12
+ assert_equal [2, 3, 4, 0, 0, 0], MarsDateTime.new(2, 3, 4).ymshms
13
+ assert_equal [5, 4, 24, 0, 0, 0], MarsDateTime.new(5, 4, 24).ymshms
14
+ assert_equal [1054, 20, 20, 0, 0, 0], MarsDateTime.new(1054, 20, 20).ymshms
15
+ end
7
16
 
8
- class MarsDateTest < MiniTest::Unit::TestCase
17
+ def test_year1_sol1_is_sunday
18
+ assert_equal 0, MarsDateTime.new(1, 1, 1).dow
19
+ assert_equal 'Sunday', MarsDateTime.new(1, 1, 1).day_of_week
20
+ end
9
21
 
10
- def my_assert(expr)
11
- if !expr && block_given?
12
- puts "\n--- DEBUG: "
13
- yield
14
- end
15
- assert(expr)
22
+ def test_epoch_msd
23
+ m = MarsDateTime.new(1, 1, 1)
24
+ assert_equal MarsDateTime::EPOCH_MSD, m.msd
25
+ assert_equal 1, m.epoch_sol
16
26
  end
17
27
 
18
- def my_assert_equal(e1, e2)
19
- if e1 != e2 && block_given?
20
- puts "\n--- DEBUG: "
21
- yield
22
- end
23
- assert_equal(e1, e2)
28
+ def test_accessors_ymshms_mxt
29
+ m = MarsDateTime.new(1043, 2, 15, 12, 34, 45)
30
+ assert_equal 1043, m.myear
31
+ assert_equal 2, m.month
32
+ assert_equal 15, m.sol
33
+ assert_equal 12, m.mxt_hour
34
+ assert_equal 34, m.mxt_min
35
+ assert_in_delta 45.0, m.mxt_sec, 0.001
36
+ assert_equal 4, m.dow
37
+ assert_equal 'Thursday', m.day_of_week
38
+ assert_equal 43, m.year_sol
39
+ assert_equal 696715, m.epoch_sol
40
+ assert_equal [1043, 2, 15, 12, 34, 45], m.ymshms
24
41
  end
25
42
 
26
- ## experimenting...
27
-
28
- context "Mars date 1/1/1" do
29
- md = MarsDateTime.new(1,1,1)
30
- should "compute backwards to same result" do
31
- assert_equal([1,1,1,0,0,0],md.ymshms)
32
- end
33
- should "be a Sunday" do
34
- assert_equal(0,md.dow)
35
- end
43
+ def test_named_constructors
44
+ a = MarsDateTime.new(1043, 2, 15, 12, 34, 45)
45
+ b = MarsDateTime.mxt(1043, 2, 15, 12, 34, 45)
46
+ assert_in_delta 0, a - b, 0
47
+ assert_equal a.msd, MarsDateTime.at(a.msd).msd
48
+ assert_equal a.msd, MarsDateTime.from_msd(a.msd).msd
49
+
50
+ m = MarsDateTime.mtc(1, 1, 1, 15, 46, 58)
51
+ assert_equal 15, m.mtc.hour
52
+ assert_equal 46, m.mtc.min
53
+ assert_in_delta 58.0, m.mtc.sec, 0.5
54
+ assert_equal [1, 1, 1], [m.year, m.month, m.sol]
36
55
  end
37
56
 
38
- context "Mars date 2/3/4" do
39
- md = MarsDateTime.new(2,3,4)
40
- should "compute backwards to same result" do
41
- assert_equal([2,3,4,0,0,0],md.ymshms)
42
- end
57
+ def test_mxt_and_mtc_midnight_are_the_same_instant
58
+ a = MarsDateTime.mxt(1077, 23, 6)
59
+ b = MarsDateTime.mtc(1077, 23, 6)
60
+ assert_in_delta 0, a - b, 0
61
+ assert_equal 0, a.mxt.hour
62
+ assert_equal 0, a.mtc.hour
43
63
  end
44
64
 
45
- context "Mars date 5/4/24" do
46
- md = MarsDateTime.new(5,4,24)
47
- should "compute backwards to same result" do
48
- assert_equal([5,4,24,0,0,0],md.ymshms)
49
- end
65
+ def test_clock_views
66
+ m = MarsDateTime.mxt(1, 1, 1, 13, 0, 0)
67
+ assert_equal 13, m.mxt.hour
68
+ assert_equal 0, m.mxt.min
69
+ assert_in_delta 0.0, m.mxt.sec, 0.001
70
+ assert_equal :mxt, m.mxt.scale
71
+ assert_equal :mtc, m.mtc.scale
72
+ assert_equal m.format_mxt, m.mxt.to_s
73
+ assert_equal m.format_mtc, m.mtc.to_s
74
+ assert_equal '13', m.format('%H')
75
+ assert_equal '13', m.format_mxt('%H')
76
+ assert_equal '13', m.mxt.format('%H')
77
+ assert_equal '12', m.format_mtc('%H')
78
+ assert_equal '12', m.mtc.format('%H')
79
+ assert_equal 'MXT', m.format('%Z')
80
+ assert_equal 'MXT', m.mxt.format('%Z')
81
+ assert_equal 'MTC', m.format_mtc('%Z')
82
+ assert_equal 'MTC', m.mtc.format('%Z')
83
+ assert_equal '13:00:00 MXT', m.format('%H:%M:%S %Z')
84
+ assert_equal '12:39:07 MTC', m.format_mtc('%H:%M:%S %Z')
85
+ assert_equal m.year, m.mxt.year
86
+ assert_equal m.month_name, m.mtc.month_name
87
+ refute_respond_to m, :strftime
50
88
  end
51
89
 
52
- context "Mars date 1054/20/20" do
53
- md = MarsDateTime.new(1054,20,20)
54
- should "compute backwards to same result" do
55
- assert_equal([1054,20,20,0,0,0],md.ymshms)
56
- end
90
+ def test_at_rolls_into_next_sol
91
+ midnight = MarsDateTime.mxt(1, 1, 1)
92
+ nxt = MarsDateTime.at(midnight.msd + 1)
93
+ assert_equal [1, 1, 2], [nxt.year, nxt.month, nxt.sol]
57
94
  end
58
95
 
59
- context "Earth date 1/1/22" do
60
- ed = DateTime.new(1,1,22)
61
- md = MarsDateTime.new(ed)
62
- should "be approximately M-date 1/1/1" do
63
- assert_equal([1,1,1],md.ymshms[0..2])
64
- end
65
- should "yield a Martian Sunday" do
66
- assert_equal(md.day_of_week,"Sunday")
67
- end
96
+ def test_accessors_933
97
+ m = MarsDateTime.new(933, 1, 2)
98
+ assert_equal [933, 1, 2], [m.myear, m.month, m.sol]
99
+ m = MarsDateTime.new(933, 1, 1)
100
+ assert_equal [933, 1, 1], [m.myear, m.month, m.sol]
68
101
  end
69
102
 
70
- context "Earth date May 23, 1961" do
71
- e = DateTime.new(1961,5,23)
72
- m = MarsDateTime.new(e)
73
- should "yield a Martian Friday" do
74
- assert_equal(m.day_of_week,"Friday")
75
- end
103
+ def test_taurus_25_leap_only
104
+ assert MarsDateTime.leap?(1067)
105
+ MarsDateTime.new(1067, 24, 25)
106
+ refute MarsDateTime.leap?(1066)
107
+ assert_raises(ArgumentError) { MarsDateTime.new(1066, 24, 25) }
76
108
  end
77
109
 
78
- context "Earth date May 24, 1961" do
79
- e = DateTime.new(1961,5,24)
80
- m = MarsDateTime.new(e)
81
- should "yield a Martian Saturday" do
82
- assert_equal(m.day_of_week,"Saturday")
83
- # my_assert_equal(m.day_of_week,"Friday") { p m }
84
- end
110
+ def test_reject_invalid_clocks
111
+ assert_raises(ArgumentError) { MarsDateTime.new(1, 1, 1, 24, 40, 0) }
112
+ assert_raises(ArgumentError) { MarsDateTime.mtc(1, 1, 1, 24, 0, 0) }
113
+ assert_raises(ArgumentError) { MarsDateTime.new(1, 1, 1, 25, 0, 0) }
114
+ MarsDateTime.new(1, 1, 1, 24, 39, 35) # last MXT second, ok
85
115
  end
86
116
 
87
- context "A Martian date/time (y,m,s,h,m,s)" do ###
88
- m = MarsDateTime.new(1043,2,15,12,34,45)
89
- should "set all its accessors properly" do
90
- assert_equal(1043,m.myear)
91
- assert_equal(2,m.month)
92
- assert_equal(15,m.sol)
93
- assert_equal(12,m.hr)
94
- assert_equal(34,m.min)
95
- assert_equal(45,m.sec)
96
- assert_equal(4,m.dow)
97
- assert_equal("Thursday",m.day_of_week)
98
- assert_equal(43,m.year_sol)
99
- assert_equal(696715,m.epoch_sol)
100
- end
117
+ def test_earth_before_epoch_rejected
118
+ assert_raises(ArgumentError) { MarsDateTime.new(DateTime.new(1, 1, 22)) }
101
119
  end
102
120
 
103
- context "The 2007 Martian equinox" do ###
104
- e = DateTime.new(2007,12,9,17,20,0)
105
- m = MarsDateTime.new(e)
106
- m11 = MarsDateTime.new(1068,1,1)
107
- should "fall on or near 1/1 (MCE)" do
108
- diff = (m11-m).abs
109
- flag = diff < 1.5
110
- assert(flag)
111
- end
121
+ def test_official_mtc_examples
122
+ m = MarsDateTime.new(DateTime.new(2000, 1, 6, 0, 0, 0))
123
+ assert_equal [1063, 19, 21], [m.year, m.month, m.sol]
124
+ assert_equal 23, m.mtc_hour
125
+ assert_equal 59, m.mtc_min
126
+ assert_in_delta 39.3, m.mtc_sec, 1.0
127
+
128
+ m = MarsDateTime.new(DateTime.new(2026, 8, 13, 0, 6, 56))
129
+ assert_equal [1077, 23, 6], [m.year, m.month, m.sol]
130
+ mtc_hours = m.mtc_hour + m.mtc_min / 60.0 + m.mtc_sec / 3600.0
131
+ assert_in_delta 1 + 6 / 60.0 + 22 / 3600.0, mtc_hours, 2.0 / 3600.0
112
132
  end
113
133
 
114
- context "Constructing without parameters" do
115
- m = MarsDateTime.new
116
- e = DateTime.now
117
- m2e = m.earth_date
118
- should "default to today" do
119
- diff = (e-m2e).abs # m - e doesn't work!
120
- assert(diff < 1.0)
121
- end
134
+ def test_offset_independent
135
+ utc = DateTime.new(2000, 1, 1, 12, 0, 0)
136
+ est = utc.new_offset(Rational(-5, 24))
137
+ assert_in_delta MarsDateTime.new(utc).msd, MarsDateTime.new(est).msd, 1e-12
122
138
  end
123
139
 
124
- context "Constructing with a DateTime" do
125
- should "convert from Gregorian to MCE" do
126
- e = DateTime.new(1902,8,12,7,0,0)
127
- m = MarsDateTime.new(e)
128
- diff = (m.earth_date - e).abs # days as a float
129
- x = assert(diff < 1.0)
130
- end
140
+ def test_equinoxes_near_following_new_year
141
+ m = MarsDateTime.new(DateTime.new(2007, 12, 9, 17, 20, 0))
142
+ assert_in_delta 0, MarsDateTime.new(1068, 1, 1) - m, 1.5
143
+
144
+ m = MarsDateTime.new(DateTime.new(1609, 3, 12))
145
+ assert_in_delta 0, MarsDateTime.new(856, 1, 1) - m, 1.5
146
+
147
+ m = MarsDateTime.new(DateTime.new(1902, 8, 12, 7, 0, 0))
148
+ assert_in_delta 0, MarsDateTime.new(1012, 1, 1) - m, 1.5
131
149
  end
132
150
 
133
- context "A Martian date/time (933,1,2)" do
134
- m = MarsDateTime.new(933,1,2)
135
- should "set the three obvious accessors properly" do
136
- assert_equal(933,m.myear)
137
- assert_equal(1,m.month)
138
- assert_equal(2,m.sol)
139
- end
151
+ def test_default_constructor_is_now
152
+ assert_in_delta 0, DateTime.now - MarsDateTime.new.earth_date, 1.0
140
153
  end
141
154
 
142
- context "A Martian date/time (933,1,1)" do
143
- m = MarsDateTime.new(933,1,1)
144
- should "set the three obvious accessors properly" do
145
- assert_equal(933,m.myear)
146
- assert_equal(1,m.month)
147
- assert_equal(1,m.sol)
148
- end
155
+ def test_today_is_current_mars_midnight
156
+ n = MarsDateTime.now
157
+ t = MarsDateTime.today
158
+ assert_equal n.year, t.year
159
+ assert_equal n.month, t.month
160
+ assert_equal n.sol, t.sol
161
+ assert_equal 0, t.mxt_hour
162
+ assert_equal 0, t.mxt_min
163
+ assert_in_delta 0.0, t.mxt_sec, 1e-9
164
+ assert_in_delta 0.0, t.mtc_hour, 1e-9
165
+ assert_operator n.msd - t.msd, :>=, 0
166
+ assert_operator n.msd - t.msd, :<, 1.0
149
167
  end
150
168
 
151
- context "The Martian date 24/25" do
152
- context "in a leap year" do
153
- year = 1067
154
- should "exist" do
155
- assert( MarsDateTime.leap?(year) )
156
- assert_nothing_raised { MarsDateTime.new(year,24,25) }
157
- end
158
- end
159
- context "in a non-leap year" do
160
- year = 1066
161
- should "not exist" do
162
- assert( ! MarsDateTime.leap?(year) )
163
- assert_raise(RuntimeError) { MarsDateTime.new(year,24,25) }
164
- end
165
- end
169
+ def test_earth_date_of_mars_epoch
170
+ e = MarsDateTime.new(1, 1, 1).earth_date
171
+ assert_equal 1, e.year
172
+ assert_equal 1, e.month
173
+ assert_in_delta 23, e.day, 1
174
+ cap = MarsDateTime.epoch_caption
175
+ assert_equal e.year, cap[:epoch_earth_if_tt_were_ut].year
176
+ assert_equal e.day, cap[:epoch_earth_if_tt_were_ut].day
177
+ assert_match(/TT as UT/, cap[:caveat])
166
178
  end
167
179
 
168
- context "The earth_date convertor" do
169
- m = MarsDateTime.new(1,1,1)
170
- should "convert to a Gregorian date" do
171
- e = m.earth_date
172
- assert_equal(1,e.year)
173
- assert_equal(1,e.month)
174
- assert((e.day-22).abs <= 1)
175
- end
180
+ def test_earth_datetime_round_trip
181
+ e = DateTime.new(1902, 8, 12, 7, 0, 0)
182
+ assert_in_delta 0, MarsDateTime.new(e).earth_date - e, 1.0 / 86400.0
176
183
  end
177
184
 
178
- context "An Earthly date" do
179
- e1 = DateTime.new(1961,5,31)
180
- should "(approximately) make the conversion roundtrip" do
181
- m1 = MarsDateTime.new(e1)
182
- e2 = m1.earth_date
183
- diff = e2 - e1
184
- assert(diff.abs <= 0.01)
185
- end
185
+ def test_earth_round_trip
186
+ e1 = DateTime.new(1961, 5, 31)
187
+ e2 = MarsDateTime.new(e1).earth_date
188
+ assert_in_delta 0, e2 - e1, 1.0 / 86400.0
186
189
  end
187
190
 
188
- context "A Martian date" do
189
- m1 = MarsDateTime.new(1067,1,1)
190
- should "(approximately) make the conversion roundtrip" do
191
- e1 = m1.earth_date
192
- m2 = MarsDateTime.new(e1)
193
- diff = m2 - m1
194
- assert(diff.abs < 0.01)
195
- end
191
+ def test_mars_round_trip
192
+ m1 = MarsDateTime.new(1067, 1, 1)
193
+ m2 = MarsDateTime.new(m1.earth_date)
194
+ assert_in_delta 0, m2 - m1, 1e-8
196
195
  end
197
196
 
198
- context "An arbitrary Martian date" do
199
- m1 = MarsDateTime.new(1069,15,24)
200
- m2 = MarsDateTime.new(933,6,4)
201
- m3 = MarsDateTime.new(1055,14,1)
202
- should "format well with strftime" do
203
- assert_equal("Mon",m1.strftime("%a"))
204
- assert_equal("Monday",m1.strftime("%A"))
205
- assert_equal("Aug",m1.strftime("%b"))
206
- assert_equal("August",m1.strftime("%B"))
207
- assert_equal("24",m1.strftime("%d"))
208
- assert_equal("24",m1.strftime("%e"))
209
- assert_equal("1069-15-24",m1.strftime("%F"))
210
- assert_equal("416",m1.strftime("%j"))
211
- assert_equal("15",m1.strftime("%m"))
212
- assert_equal("0",m1.strftime("%s"))
213
- assert_equal("2",m1.strftime("%u"))
214
- assert_equal("60",m1.strftime("%U"))
215
- assert_equal("1",m1.strftime("%w"))
216
- assert_equal("1069/15/24",m1.strftime("%x"))
217
- assert_equal("1069",m1.strftime("%Y"))
218
- assert_equal("\n",m1.strftime("%n"))
219
- assert_equal("\t",m1.strftime("%t"))
220
- assert_equal("%",m1.strftime("%%"))
221
-
222
- assert_equal("Wed",m2.strftime("%a"))
223
- assert_equal("Wednesday",m2.strftime("%A"))
224
- assert_equal("Leo",m2.strftime("%b"))
225
- assert_equal("Leo",m2.strftime("%B"))
226
- assert_equal("04",m2.strftime("%d"))
227
- assert_equal(" 4",m2.strftime("%e"))
228
- assert_equal("933-6-4",m2.strftime("%F"))
229
- assert_equal("144",m2.strftime("%j"))
230
- assert_equal("6",m2.strftime("%m"))
231
- assert_equal("0",m2.strftime("%s"))
232
- assert_equal("4",m2.strftime("%u"))
233
- assert_equal("21",m2.strftime("%U"))
234
- assert_equal("3",m2.strftime("%w"))
235
- assert_equal("933/06/04",m2.strftime("%x"))
236
- assert_equal("933",m2.strftime("%Y"))
237
-
238
- assert_equal("Sag",m3.strftime("%b"))
239
- assert_equal("Sagittarius",m3.strftime("%B"))
197
+ def test_earth_round_trip_with_hms
198
+ e1 = DateTime.new(1976, 7, 4, 16, 30, 0)
199
+ 30.times do
200
+ e2 = MarsDateTime.new(e1).earth_date
201
+ assert_in_delta 0, e2 - e1, 1.0 / 86400.0
202
+ e1 += 1
240
203
  end
241
204
  end
242
205
 
243
- context "An Earthly date with h:m:s" do
244
- e1 = DateTime.new(1976,7,4,16,30,0) # July 4, 1976 16:30
245
- m1 = MarsDateTime.new(e1)
246
- should "make the conversion roundtrip" do
247
- 30.times do
248
- m1 = MarsDateTime.new(e1)
249
- e2 = m1.earth_date
250
- diff = e2 - e1
251
- assert(diff.abs <= 0.01) { STDERR.puts " diff = #{diff}" }
252
- e1 += 1
253
- end
254
- end
206
+ def test_format_dates
207
+ m1 = MarsDateTime.new(1069, 15, 24)
208
+ m2 = MarsDateTime.new(933, 6, 4)
209
+ m3 = MarsDateTime.new(1055, 14, 1)
210
+
211
+ assert_equal 'Mon', m1.format('%a')
212
+ assert_equal 'Monday', m1.format('%A')
213
+ assert_equal 'Aug', m1.format('%b')
214
+ assert_equal 'M-August', m1.format('%B')
215
+ assert_equal '24', m1.format('%d')
216
+ assert_equal '24', m1.format('%e')
217
+ assert_equal '1069-15-24', m1.format('%F')
218
+ assert_equal '416', m1.format('%j')
219
+ assert_equal '15', m1.format('%m')
220
+ assert_equal '0', m1.format('%s')
221
+ assert_equal '2', m1.format('%u')
222
+ assert_equal '60', m1.format('%U')
223
+ assert_equal '1', m1.format('%w')
224
+ assert_equal '1069/15/24', m1.format('%x')
225
+ assert_equal '1069', m1.format('%Y')
226
+ assert_equal "\n", m1.format('%n')
227
+ assert_equal "\t", m1.format('%t')
228
+ assert_equal '%', m1.format('%%')
229
+
230
+ assert_equal 'Wed', m2.format('%a')
231
+ assert_equal 'Wednesday', m2.format('%A')
232
+ assert_equal 'Leo', m2.format('%b')
233
+ assert_equal 'Leo', m2.format('%B')
234
+ assert_equal '04', m2.format('%d')
235
+ assert_equal ' 4', m2.format('%e')
236
+ assert_equal '933-06-04', m2.format('%F')
237
+ assert_equal '144', m2.format('%j')
238
+ assert_equal '06', m2.format('%m')
239
+ assert_equal '0', m2.format('%s')
240
+ assert_equal '4', m2.format('%u')
241
+ assert_equal '21', m2.format('%U')
242
+ assert_equal '3', m2.format('%w')
243
+ assert_equal '933/06/04', m2.format('%x')
244
+ assert_equal '933', m2.format('%Y')
245
+
246
+ assert_equal 'Sag', m3.format('%b')
247
+ assert_equal 'Sagittarius', m3.format('%B')
248
+
249
+ line = '%A, %B %e, %Y %H:%M:%S'
250
+ assert_equal m1.format(line), m1.format_mxt(line)
251
+ assert_equal m1.format(line), m1.mxt.format(line)
252
+ assert_equal m1.format_mtc(line), m1.mtc.format(line)
255
253
  end
256
254
 
257
- context "Martian dates" do
258
- m1 = MarsDateTime.new(1068,14,22)
259
- m2 = MarsDateTime.new(1068,14,21)
260
- e1 = DateTime.new(2002,4,19)
261
- e2 = DateTime.new(2012,9,29)
262
- should "compare with each other" do
263
- assert(m1 > m2)
264
- assert(m2 < m1)
265
- end
266
- should "compare with Earth dates" do
267
- assert(m1 > e1)
268
- assert(m2 < e2)
269
- end
270
- should "honor equality (within roundoff)" do
271
- assert(m1 == m1)
272
- assert(m1 != m2)
273
- end
274
- end
275
-
276
- context "The 'now' and 'today' class methods" do
277
- t1 = MarsDateTime.now
278
- t0 = MarsDateTime.today
279
- should "be less than a day apart" do
280
- diff = t1 - t0
281
- assert(diff < 1.0)
282
- end
255
+ def test_format_clocks_at_midnight
256
+ m = MarsDateTime.new(1, 1, 1)
257
+ assert_equal '00', m.format('%H')
258
+ assert_equal '00', m.format_mtc('%H')
259
+ assert_equal '00:00:00', m.format('%X')
260
+ assert_equal '%P', m.format('%P')
261
+ assert_equal 'foo%', m.format('foo%')
262
+ assert_equal '%', m.format('%')
263
+ assert_equal 'x%', m.format('x%%')
283
264
  end
284
265
 
285
- context "In M-year 1043, each month" do
286
- md = (1..24).to_a.map {|mm| MarsDateTime.new(1043,mm,1) }
287
- should "start on a Thursday" do
288
- md.each {|m| assert(m.day_of_week == "Thursday") }
289
- end
266
+ def test_mtc_just_before_midnight_stays_on_previous_sol
267
+ next_midnight = (MarsDateTime::EPOCH_MSD + 11).to_f
268
+ m = MarsDateTime.at(next_midnight.prev_float)
269
+
270
+ assert_equal [1, 1, 11], [m.year, m.month, m.sol]
271
+ assert_equal [23, 59], [m.mtc_hour, m.mtc_min]
272
+ assert_operator m.mtc_sec, :<, 60
273
+ assert_equal '23:59:59.999', m.format_mtc
274
+ assert_equal '23:59:59 MTC', m.format_mtc('%H:%M:%S %Z')
290
275
  end
291
276
 
292
- context "Converting 1961/5/31 to Martian" do
293
- e = DateTime.new(1961,5,31)
294
- m = MarsDateTime.new(e)
295
- should "yield M-April 10, 1043 MCE" do
296
- assert(m.year == 1043)
297
- assert(m.month == 7)
298
- assert(m.sol == 10)
299
- end
300
- should "give a Martian Saturday" do
301
- assert(m.day_of_week == "Saturday")
302
- end
277
+ def test_date_is_a_valid_operand
278
+ d = Date.new(2010, 1, 1)
279
+ m = MarsDateTime.new(d)
280
+ assert_in_delta 0, m - d, 1e-9
281
+ assert_equal 0, m <=> d
303
282
  end
304
283
 
305
- context "The 1609 Martian equinox" do
306
- e = DateTime.new(1609,3,12)
307
- m = MarsDateTime.new(e)
308
- m11 = MarsDateTime.new(856,1,1)
309
- should "fall on or near 1/1 (MCE)" do
310
- diff = (m11-m).abs
311
- assert(diff < 1.5)
312
- end
284
+ def test_taurus_past_end_is_rejected
285
+ assert_raises(ArgumentError) { MarsDateTime.new(1, 24, 26) }
286
+ assert_raises(ArgumentError) { MarsDateTime.new(1, 24, 28) }
313
287
  end
314
288
 
315
- context "The 1902 Martian equinox" do
316
- e = DateTime.new(1902,8,12,7,0,0)
317
- m = MarsDateTime.new(e)
318
- m11 = MarsDateTime.new(1012,1,1)
319
- should "fall on or near 1/1 (MCE)" do
320
- diff = (m11-m).abs
321
- assert(diff < 1.5)
322
- end
289
+ def test_comparisons
290
+ m1 = MarsDateTime.new(1068, 14, 22)
291
+ m2 = MarsDateTime.new(1068, 14, 21)
292
+ e1 = DateTime.new(2002, 4, 19)
293
+ e2 = DateTime.new(2012, 9, 29)
294
+ assert_operator m1, :>, m2
295
+ assert_operator m2, :<, m1
296
+ assert_operator m1, :>, e1
297
+ assert_operator m2, :<, e2
298
+ assert_equal m1, m1
299
+ refute_equal m1, m2
323
300
  end
324
301
 
325
- context "A Martian date" do
326
- m = MarsDateTime.new(1068,1,1)
327
- context "plus 7 days" do
328
- m2 = m + 7
329
- should "be the same day of the week" do
330
- assert_equal(m.day_of_week, m2.day_of_week)
331
- end
332
- end
333
- context "plus 14 days" do
334
- m3 = m + 14
335
- should "be the same day of the week" do
336
- assert_equal(m.day_of_week, m3.day_of_week)
337
- end
338
- end
339
- context "plus 21 days" do
340
- m4 = m + 21
341
- should "be the same day of the week" do
342
- assert_equal(m.day_of_week, m4.day_of_week)
343
- end
302
+ def test_year_1043_months_start_thursday
303
+ (1..24).each do |mm|
304
+ assert_equal 'Thursday', MarsDateTime.new(1043, mm, 1).day_of_week
344
305
  end
345
306
  end
346
307
 
347
- context "Martian April 1, 1043" do
348
- m = MarsDateTime.new(1043,7,1)
349
- should "be a Thursday" do
350
- assert_equal(m.day_of_week,"Thursday")
351
- end
308
+ def test_earth_1961_may_31
309
+ m = MarsDateTime.new(DateTime.new(1961, 5, 31))
310
+ assert_equal 1043, m.year
311
+ assert_equal 7, m.month
312
+ assert_equal 8, m.sol
313
+ assert_equal 'Thursday', m.day_of_week
352
314
  end
353
-
354
- context "A Martian date" do
355
- md = MarsDateTime.new(1062,20,20)
356
- m2 = MarsDateTime.new(1062,20,17)
357
- should "allow subtraction of another date" do
358
- m = md - m2
359
- assert( (m - 3.0) < 0.01) # sols
360
- end
361
- should "allow subtraction of an Earth date" do
362
- e = DateTime.new(1998, 3, 12, 16, 45, 0)
363
- m = md - e
364
- assert( (m - 3.0) < 0.01) # sols
365
- end
366
- should "allow subtraction of a Fixnum" do
367
- m = md - 3 # sols
368
- assert( (m - m2) < 0.01)
369
- end
370
- should "allow subtraction of a Float" do
371
- m = md - 3.0 # sols
372
- assert( (m - m2) < 0.01)
373
- end
315
+
316
+ def test_martian_april_1_1043_is_thursday
317
+ assert_equal 'Thursday', MarsDateTime.new(1043, 7, 1).day_of_week
374
318
  end
375
319
 
376
- end
320
+ def test_plus_weeks_keeps_weekday
321
+ m = MarsDateTime.new(1068, 1, 1)
322
+ assert_equal m.day_of_week, (m + 7).day_of_week
323
+ assert_equal m.day_of_week, (m + 14).day_of_week
324
+ assert_equal m.day_of_week, (m + 21).day_of_week
325
+ end
326
+
327
+ def test_addition_rolls_year
328
+ assert_equal [1067, 1, 1], (MarsDateTime.new(1066, 24, 24) + 1).ymshms[0..2]
329
+ assert_equal [1068, 1, 1], (MarsDateTime.new(1067, 24, 25) + 1).ymshms[0..2]
330
+ end
331
+
332
+ def test_subtraction
333
+ md = MarsDateTime.new(1062, 20, 20)
334
+ m2 = MarsDateTime.new(1062, 20, 17)
335
+ assert_in_delta 3.0, md - m2, 1e-9
336
+ assert_in_delta 0, (md - 3) - m2, 1e-9
337
+ assert_in_delta 0, (md - 3.0) - m2, 1e-9
338
+ e = m2.earth_date
339
+ assert_in_delta 3.0, md - e, 1e-8
340
+ d = Date.new(2000, 1, 1)
341
+ dt = DateTime.new(2000, 1, 1, 12, 0, 0)
342
+ assert MarsDateTime.new(dt) - d > 0
343
+ assert_equal 1, MarsDateTime.new(dt) <=> d
344
+ end
377
345
 
346
+ def test_from_msd_and_json
347
+ m = MarsDateTime.new(1043, 2, 15, 12, 34, 45)
348
+ m2 = MarsDateTime.from_msd(m.msd)
349
+ assert_in_delta 0, m2 - m, 0
350
+ m3 = MarsDateTime.from_json(m.to_json)
351
+ assert_in_delta 0, m3 - m, 0
352
+ assert_equal m.msd, MarsDateTime.new(m.msd).msd
353
+ end
354
+
355
+ def test_to_s_labels_both_clocks
356
+ s = MarsDateTime.new(1, 1, 1).to_s
357
+ assert_includes s, 'MXT'
358
+ assert_includes s, 'MTC'
359
+ refute_match(/\bhr\b/, s)
360
+ end
361
+
362
+ def test_no_unmarked_clock_accessors
363
+ m = MarsDateTime.new(1, 1, 1)
364
+ refute m.respond_to?(:hr)
365
+ refute m.respond_to?(:min)
366
+ refute m.respond_to?(:sec)
367
+ assert_raises(ArgumentError) { MarsDateTime.new(1, 1, 1, 0, 0, 0, clock: :mtc) }
368
+ end
369
+ end