sy 2.0.2 → 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,12 +3,12 @@
3
3
  # Qualities specific to relative magnitudes.
4
4
  #
5
5
  module SY::SignedMagnitude
6
- # Relative magnitude constructor takes :quantity (alias :of) named argument,
7
- # and :amount named argument, where :amount is allowed to be negative.
6
+ # Relative magnitude constructor takes :quantity (alias :of) argument and
7
+ # :amount argument. Amount is allowed to be negative.
8
8
  #
9
- def initialize args={}
10
- @quantity = args[:quantity] || args[:of]
11
- amnt = args[:amount]
9
+ def initialize **named_args
10
+ @quantity = named_args[:quantity] || named_args[:of]
11
+ amnt = named_args[:amount]
12
12
  @amount = case amnt
13
13
  when Numeric then amnt
14
14
  when nil then 1
data/lib/sy/unit.rb CHANGED
@@ -6,16 +6,15 @@
6
6
  module SY::Unit
7
7
  def self.pre_included target
8
8
  class << target
9
- # Overriding this method from NameMagic mixin makes sure that all Unit
10
- # subclasses have the same namespace in Unit class, rather then each
11
- # parametrized subclass its own.
9
+ # Overriding this method from NameMagic mixin ensures, that all Unit
10
+ # subclasses use common namespace (Unit), rather than each their own.
12
11
  #
13
12
  def namespace
14
13
  SY::Unit
15
14
  end
16
15
 
17
- # Tweaking instance accessor from NameMagic, to make it accept unit
18
- # abbreviations, and unit names regardless of capitalization
16
+ # Tweaking instance accessor from NameMagic to make it accept unit
17
+ # abbreviations and unit names regardless of capitalization
19
18
  #
20
19
  def instance arg
21
20
  begin
@@ -101,14 +100,11 @@ module SY::Unit
101
100
  # specified quantity. Note that :amount for standard units, if supplied, has
102
101
  # special meaning of setting the relationship of that quantity.
103
102
  #
104
- def standard args={}
105
- args.must_have :quantity, syn!: :of
106
- qnt = SY::Quantity.instance( args.delete :quantity )
107
- if args.empty? then
108
- qnt.standard_unit
109
- else
110
- qnt.new_standard_unit( args )
111
- end
103
+ def standard( of: nil, **nn )
104
+ puts "Constructing a standard unit of #{of}." if SY::DEBUG
105
+ fail ArgumentError, ":of argument missing!" if of.nil?
106
+ qnt = SY::Quantity.instance( of )
107
+ nn.empty? ? qnt.standard_unit : qnt.new_standard_unit( **nn )
112
108
  end
113
109
 
114
110
  # Unit abbreviations as a hash of abbreviation => unit pairs.
@@ -165,10 +161,8 @@ module SY::Unit
165
161
  # ambiguity with regard to standard prefixes and abbreviations thereof should
166
162
  # also be avoided.
167
163
  #
168
- def initialize args={}
169
- if args.has? :abbreviation, syn!: :short then
170
- @abbreviation = args.delete( :abbreviation ).to_sym
171
- end
164
+ def initialize( short: nil, **nn )
165
+ @abbreviation = short.to_sym if short
172
166
 
173
167
  # FIXME: Here, we would have to watch out for :amount being set
174
168
  # if it is a number, amount is in standard units
@@ -176,7 +170,7 @@ module SY::Unit
176
170
  # it estableshes a relationship between this and that quantity. It means that
177
171
  # the unit amount automatically becomes ... one ... and such relationship can
178
172
  # only be established for standard quantity
179
- super args
173
+ super( **nn )
180
174
  end
181
175
 
182
176
  # Addition: Unit is converted to a magnitude before the operation.
data/lib/sy/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module SY
2
- VERSION = "2.0.2"
2
+ VERSION = "2.0.4"
3
3
  DEBUG = false # debug mode switch - sometimes there are lines like
4
4
  # puts "something" if SY::DEBUG
5
5
  end
data/test/sy_test.rb CHANGED
@@ -65,17 +65,17 @@ describe SY::Dimension do
65
65
  end
66
66
  end
67
67
 
68
- describe SY::Mapping do
68
+ describe SY::Measure do
69
69
  it "should" do
70
- i = SY::Mapping.identity
71
- a, b = SY::Mapping.new( 2 ), SY::Mapping.new( 3 )
70
+ i = SY::Measure.identity
71
+ a, b = SY::Measure.new( ratio: 2 ), SY::Measure.new( ratio: 3 )
72
72
  assert_equal 1, i.ratio
73
- assert_equal 4, a.im.( 8 )
74
- assert_equal 3, b.ex.( 1 )
75
- assert_equal 6, (a * b).ex.( 1 )
76
- assert_equal 2, (a * b / b).ex.( 1 )
77
- assert_equal 4, (a ** 2).ex.( 1 )
78
- assert_equal 2, a.inverse.im.( 1 )
73
+ assert_equal 4, a.r.( 8 )
74
+ assert_equal 3, b.w.( 1 )
75
+ assert_equal 6, (a * b).w.( 1 )
76
+ assert_equal 2, (a * b / b).w.( 1 )
77
+ assert_equal 4, (a ** 2).w.( 1 )
78
+ assert_equal 2, a.inverse.r.( 1 )
79
79
  end
80
80
  end
81
81
 
@@ -98,7 +98,7 @@ describe SY::Composition do
98
98
  SY::Composition[ SY::Amount => 1, SY::Length => 1 ]
99
99
  .to_quantity.dimension )
100
100
  assert_equal SY.Dimension( 'L' ), l.dimension
101
- assert_kind_of SY::Mapping, a.infer_mapping
101
+ assert_kind_of SY::Measure, a.infer_measure
102
102
  end
103
103
  end
104
104
 
@@ -109,7 +109,7 @@ describe SY::Quantity, SY::Magnitude do
109
109
  @amount_in_dozens = begin
110
110
  SY.Quantity( "AmountInDozens" )
111
111
  rescue
112
- SY::Quantity.dimensionless mapping: 12, ɴ: "AmountInDozens"
112
+ SY::Quantity.dimensionless amount: 12, ɴ: "AmountInDozens"
113
113
  end
114
114
  @inch_length = begin
115
115
  SY.Quantity( "InchLength" )
@@ -129,15 +129,15 @@ describe SY::Quantity, SY::Magnitude do
129
129
  @amount_in_dozens.must_be_kind_of SY::Quantity
130
130
  d1 = @amount_in_dozens.magnitude 1
131
131
  a12 = SY::Amount.magnitude 12
132
- mda = @amount_in_dozens.mapping_to SY::Amount
133
- i, e = mda.im, mda.ex
134
- ia = i.( a12.amount )
135
- @amount_in_dozens.magnitude ia
136
- im = @amount_in_dozens.import( a12 )
132
+ mda = @amount_in_dozens.measure of: SY::Amount
133
+ r, w = mda.r, mda.w
134
+ ra = r.( a12.amount )
135
+ @amount_in_dozens.magnitude ra
136
+ ra = @amount_in_dozens.read( a12 )
137
137
  assert_equal @amount_in_dozens.magnitude( 1 ),
138
- @amount_in_dozens.import( SY::Amount.magnitude( 12 ) )
138
+ @amount_in_dozens.read( SY::Amount.magnitude( 12 ) )
139
139
  assert_equal SY::Amount.magnitude( 12 ),
140
- @amount_in_dozens.export( 1, SY::Amount )
140
+ @amount_in_dozens.write( 1, SY::Amount )
141
141
  SY::Length.composition.must_equal SY::Composition.singular( :Length )
142
142
  end
143
143
 
@@ -147,7 +147,7 @@ describe SY::Quantity, SY::Magnitude do
147
147
  @inch = SY::Unit.standard( of: @inch_length, amount: 2.54.cm,
148
148
  ɴ: 'inch', short: '”' )
149
149
  @i1 = @inch_length.magnitude 1
150
- @il_mapping = @inch_length.mapping_to SY::Length
150
+ @il_measure = @inch_length.measure( of: SY::Length )
151
151
  end
152
152
 
153
153
  it "should" do
@@ -155,12 +155,12 @@ describe SY::Quantity, SY::Magnitude do
155
155
  @inch_length.colleague.name.must_equal :InchLength±
156
156
  @m1.to_s.must_equal "1.m"
157
157
  @i1.amount.must_equal 1
158
- assert_kind_of SY::Mapping, @il_mapping
159
- assert_kind_of Numeric, @il_mapping.ratio
160
- assert_in_epsilon 0.0254, @il_mapping.ratio
161
- @il_mapping.ex.( 1 ).must_be_within_epsilon 0.0254
158
+ assert_kind_of SY::Measure, @il_measure
159
+ assert_kind_of Numeric, @il_measure.ratio
160
+ assert_in_epsilon 0.0254, @il_measure.ratio
161
+ @il_measure.w.( 1 ).must_be_within_epsilon 0.0254
162
162
  begin
163
- impossible_mapping = @inch_length.mapping_to SY::Amount
163
+ impossible_mapping = @inch_length.measure( of: SY::Amount )
164
164
  rescue SY::DimensionError
165
165
  :dimension_error
166
166
  end.must_equal :dimension_error
@@ -172,214 +172,214 @@ describe SY::Quantity, SY::Magnitude do
172
172
  1.inch.in( :mm ).must_equal 25.4
173
173
  end
174
174
  end
175
- end
176
-
177
- describe "expected behavior" do
178
- it "should" do
179
- # Length quantity and typical units
180
- SY::METRE.must_be_kind_of SY::Unit
181
- SY::METRE.absolute?.must_equal true
182
- 1.metre.absolute.must_equal SY::METRE
183
- assert 1.metre.absolute != 1.metre.relative
184
- 1.metre.relative.relative?.must_equal true
185
-
186
-
187
- SY::METRE.relative.must_equal 1.metre
188
- 1.m.must_equal 1.metre
189
- 1.m.must_equal 1000.mm
190
- SY::METRE.quantity.name.must_equal :Length
191
- assert_in_delta 0.9.µm, 900.nm, 1e-6.nm
192
- [ 1.m, 1.m ].min.must_equal 1.m
193
- 1.m + 1.m == 1.m
194
- assert_in_epsilon 1.m, 1.m, 0.1
195
- 600.m.must_equal 0.6.km
196
- SY::METRE.quantity.must_equal SY::Length
197
- SY::Length.dimension.must_equal SY.Dimension( :L )
198
- SY.Dimension( :L ).standard_quantity.must_equal SY::Length
199
- SY::Length.standard_unit.must_equal SY::METRE
200
- SY::METRE.amount.must_equal 1
201
- SY::METRE.mili.amount.must_equal 0.001
202
- 3.km.in( :dm ).must_equal 30_000
203
- ( 1.m + 20.cm ).must_equal 1_200.mm
204
- assert 1.mm.object_id != 1.mm.object_id
205
- assert 1.mm == 1.mm
206
- assert 1.01.m != 1.m
207
- assert_equal 1, 1.01.m <=> 1.m
208
- assert_equal 0, 1.00.m <=> 1.m
209
- assert_equal -1, 0.99.m <=> 1.m
210
- assert 0.9.mm < 1.mm
211
- assert 1.1.mm > 1.09.mm
212
- assert ( 0.1.m - ( 1.m - 0.9.m ) ).abs < 1.nm.abs
213
- # Mass quantity and typical units
214
- SY::KILOGRAM.must_be_kind_of SY::Unit
215
- SY::GRAM.must_be_kind_of SY::Unit
216
- assert SY::Mass.standard_unit.equal?( SY::KILOGRAM )
217
- 1.kilogram.must_be_kind_of SY::Magnitude
218
- 1.gram.must_be_kind_of SY::Magnitude
219
- 1.kilogram.absolute.quantity.must_equal SY::Mass
220
- 1.gram.absolute.quantity.must_equal SY::Mass
221
- ( SY::KILOGRAM * 1 ).must_equal SY::GRAM * 1000
222
- 1.kilogram.must_equal 1000.g
223
- 1.kg.to_f.must_equal 1
224
- 1.g.to_f.must_equal 0.001
225
- 1.miligram.must_equal 0.001.g
226
- 1.mg.must_equal 1.miligram
227
- 1.µg.must_equal 0.001.miligram
228
- 1.ng.must_equal 0.001.microgram
229
- 1.pg.quantity.must_equal 0.001.nanogram.quantity
230
- 1.pg.amount.must_be_within_epsilon 0.001.nanogram.amount, 1e-6
231
- assert_equal 1.g, [1.g, 2.g].min
232
- assert_equal 1.mg, 1.g * 0.001
233
- 1.pg.abs.must_be_within_epsilon 0.001.nanogram.abs, 1e-6
234
- SY::TON.must_be_kind_of SY::Unit
235
- 1.ton.must_equal 1000.kg
236
- 1.t.must_equal 1.ton
237
- 1.kt.must_equal 1000.ton
238
- 1.Mt.must_equal 1000.kiloton
239
- 1.mm.quantity.name.must_equal :Length±
240
- SY::Length.standard_unit.must_equal SY::METRE
241
- SY::Length.standard_unit.name.must_equal :metre
242
- SY::Length.standard_unit.must_equal SY::METRE
243
- SY.Quantity( :Length ).object_id.must_equal SY::Length.object_id
244
- SY::Length.relative.object_id.must_equal SY.Quantity( :Length± ).object_id
245
- SY.Quantity( :Length± ).colleague.name.must_equal :Length
246
- SY.Quantity( :Length± ).colleague.class.must_equal SY::Quantity
247
- SY.Quantity( :Length± ).colleague.object_id.must_equal SY::Length.object_id
248
- SY.Quantity( :Length± ).send( :Unit ).object_id
249
- .must_equal SY::Length.send( :Unit ).object_id
250
- 1.mm.quantity.standard_unit.name.must_equal :metre
251
- 1.mm.to_s.must_equal "0.001.m"
252
- 1.mm.inspect.must_equal "#<±Magnitude: 0.001.m >"
253
- 1.µs.inspect.must_equal "#<±Magnitude: 1e-06.s >"
254
-
255
- SY::Area.dimension.must_equal SY.Dimension( :L² )
256
- SY::Area.composition.must_equal SY::Composition[ SY::Length => 2 ]
257
-
258
- SY::AMPERE.name.must_equal :ampere
259
- SY::AMPERE.abbreviation.must_equal :A
260
- SY::AMPERE.dimension.must_equal 1.A.dimension
261
- SY.Magnitude( of: SY::ElectricCurrent, amount: 1 ).must_equal 1.A.absolute
262
- 1.A.quantity.must_equal SY::ElectricCurrent.relative
263
- 1.A.quantity.standard_unit.name.must_equal :ampere
264
- 1.A.to_s( SY::AMPERE ).must_equal "1.A"
265
- 1.A.to_s.must_equal "1.A"
266
- 1.A.amount.must_equal 1
267
- 1.A.quantity.standard_unit.abbreviation.must_equal :A
268
- 1.A.inspect.must_equal "#<±Magnitude: 1.A >"
269
-
270
- 1.l⁻¹.reframe( SY::Molarity ).quantity.must_equal SY::Molarity
271
- x = ( SY::Nᴀ / SY::LITRE )
272
- x = x.reframe( SY::Molarity )
273
- y = 1.molar.absolute
274
- y.quantity.must_equal x.quantity
275
- y.amount.must_equal y.amount
276
- SY::MoleAmount.protected?.must_equal true
277
- SY::LitreVolume.protected?.must_equal true
278
- SY::MOLAR.quantity.name.must_equal :Molarity
279
- m = 1.µM
280
- 1.µM.quantity.relative?.must_equal true
281
- 1.µM.quantity.name.must_equal :Molarity±
282
- 1.µM.quantity.absolute.name.must_equal :Molarity
283
- 7.µM.must_be_within_epsilon 5.µM + 2.µM, 1e-6
284
- +1.s.must_equal 1.s
285
- # -1.s.must_equal -1 * 1.s # must raise
286
- assert_equal -(-(1.s)), +(1.s)
287
- 1.s⁻¹.quantity.must_equal ( 1.s ** -1 ).quantity
288
- 1.s⁻¹.quantity.must_equal ( 1 / 1.s ).quantity
289
- 1.s⁻¹.amount.must_equal ( 1.s ** -1 ).amount
290
- 1.s⁻¹.must_equal 1.s ** -1
291
- q1 = ( 1.s⁻¹ ).quantity
292
- q1.composition.to_hash.must_equal( { SY::Time => -1 } )
293
-
294
- q2 = ( 1 / 1.s ).quantity
295
- q2.composition.to_hash.must_equal( { SY::Time => -1 } )
296
-
297
- q1.relative?.must_equal true
298
- q2.relative?.must_equal true
299
-
300
- q1.object_id.must_equal q2.object_id
301
- ( 1.s⁻¹ ).quantity.object_id.must_equal ( 1 / 1.s ).quantity.object_id
302
- ( 1 / 1.s ).must_equal 1.s⁻¹
303
- 1.s⁻¹.( SY::Frequency ).must_equal 1.Hz
304
- # 7.°C.must_equal( 8.°C - 1.K )
305
- # (-15).°C.must_equal 258.15.K
306
- # 7000.µM.must_be_within_epsilon( 7.mM, 1e-9 )
307
- ::SY::Unit.instances.map do |i|
308
- begin
309
- i.abbreviation
310
- rescue
311
- end
312
- end.must_include :M
313
- SY::Unit.instance_names.must_include :mole
314
- # Avogadro's number is defined directly in SY
315
- 1.mol.quantity.object_id.must_equal SY::Nᴀ.( SY::MoleAmount ).quantity.object_id
316
- SY::Nᴀ.( SY::MoleAmount ).must_equal 1.mol
317
- 0.7.mol.l⁻¹.amount.must_equal 0.7
318
- 1.M.must_equal 1.mol.l⁻¹.( SY::Molarity )
319
- # (if #reframe conversion method is not used, different quantities
320
- # do not compare. Arithmetics is possible because Magnitude operators
321
- # mostly give their results only in standard quantities.
322
-
323
- # Avogadro's number is defined directly in SY
324
- 1.mol.must_equal SY::Nᴀ.unit.( SY::MoleAmount )
325
-
326
175
 
327
- 0.7.M.must_equal 0.7.mol.l⁻¹.( SY::Molarity )
328
- # (if #is_actually! conversion method is not used, current
329
- # implementation will refuse to compare different quantities,
330
- # even if their dimensions match)
331
-
332
- 30.Hz.must_equal 30.s⁻¹.( SY::Frequency )
333
-
334
- # Dalton * Avogadro must be 1 gram
335
- ( 1.Da * SY::Nᴀ ).must_be_within_epsilon( 1.g, 1e-6 )
336
-
337
- # kilogram
338
- 1.kg.must_equal 1000.g
339
- SY::Speed.dimension.must_equal SY::Dimension( "L.T⁻¹" )
340
- SY::Acceleration.dimension.must_equal SY::Dimension( "L.T⁻²" )
341
- SY::Force.dimension.must_equal SY::Dimension( "L.M.T⁻²" )
342
- ( 1.kg * 1.m.s⁻² ).( SY::Force ).must_be_within_epsilon 1.N, 1e-9
343
-
344
- # joule
345
- ( 1.N * 1.m ).( SY::Energy ).must_equal 1.J
346
- 1e-23.J.K⁻¹.must_equal 1.0e-20.mJ.K⁻¹
347
-
348
-
349
- # pascal
350
- ( 1.N / 1.m ** 2 ).( SY::Pressure ).must_be_within_epsilon 1.Pa, 1e-9
351
-
352
- # watt
353
- ( 1.V * 1.A ).( SY::Power ).must_be_within_epsilon 1.W, 1e-9
354
-
355
- # pretty representation
356
- ( 1.m / 3.s ).to_s.must_equal( "0.333.m.s⁻¹" )
357
- ( 1.m / 7.01e7.s ).to_s.must_equal( "1.43e-08.m.s⁻¹" )
358
-
359
- assert_equal 1.m, 1.s * 1.m.s⁻¹
360
- assert_equal 1.µM.s⁻¹, 1.µM / 1.s
361
- assert_equal 1.m.s⁻¹, 1.m.s( -1 )
362
- assert_equal 2_000.mm.s⁻², 2.m.s( -2 )
363
- assert_equal 3.µM, 1.µM + 2.µM
364
- assert_equal SY::Amount, SY::Molarity / SY::Molarity
365
- assert_equal SY::Amount( 1 ), 1.µM / 1.µM
366
- assert_equal SY::Amount( 1 ), 1.µM / ( 1.µM + 0.µM )
367
- assert_equal 1.µM, 1.µM * 1.µM / ( 1.µM + 0.µM )
368
- assert_in_epsilon 1.µM, 1.µmol / 1.dm( 3 ).( SY::LitreVolume )
369
-
370
- assert_equal SY::Molarity.relative, 1.mol.l⁻¹.quantity
371
-
372
- assert_equal 1 / SY::Time, 1 / SY::Time
373
- assert_equal 1 / SY::Time.relative, 1 / SY::Time
374
- assert_equal ( 1 / SY::Time.relative ), 1.mol.s⁻¹.( 1 / SY::Time ).quantity
375
- assert_equal ( 1 / SY::Time ).object_id,
376
- ( 1.0.µmol.min⁻¹.mg⁻¹ * 100.kDa ).( 1 / SY::Time ).quantity.object_id
377
- assert_equal SY::Time.magnitude( 1 ), SY::SECOND
378
- assert_equal Matrix[[60.mM], [60.mM]], Matrix[[1e-03.s⁻¹.M], [1e-3.s⁻¹.M]] * 60.s
379
-
380
- assert_equal Matrix[[5.m]], Matrix[[1.m.s⁻¹, 2.m.s⁻¹]] * Matrix.column_vector( [1.s, 2.s] )
381
- assert_equal Matrix[[2.m, 3.m], [4.m, 5.m]],
382
- Matrix[[1.m, 2.m], [3.m, 4.m]] + Matrix[[1.m, 1.m], [1.m, 1.m]]
383
- assert_equal Matrix[[5.µM]], Matrix[[1.µM]] + Matrix[[2.µM.s⁻¹]] * Matrix[[2.s]]
176
+ describe "expected behavior" do
177
+ it "should" do
178
+ # Length quantity and typical units
179
+ SY::METRE.must_be_kind_of SY::Unit
180
+ SY::METRE.absolute?.must_equal true
181
+ 1.metre.absolute.must_equal SY::METRE
182
+ assert 1.metre.absolute != 1.metre.relative
183
+ 1.metre.relative.relative?.must_equal true
184
+
185
+
186
+ SY::METRE.relative.must_equal 1.metre
187
+ 1.m.must_equal 1.metre
188
+ 1.m.must_equal 1000.mm
189
+ SY::METRE.quantity.name.must_equal :Length
190
+ assert_in_delta 0.9.µm, 900.nm, 1e-6.nm
191
+ [ 1.m, 1.m ].min.must_equal 1.m
192
+ 1.m + 1.m == 1.m
193
+ assert_in_epsilon 1.m, 1.m, 0.1
194
+ 600.m.must_equal 0.6.km
195
+ SY::METRE.quantity.must_equal SY::Length
196
+ SY::Length.dimension.must_equal SY.Dimension( :L )
197
+ SY.Dimension( :L ).standard_quantity.must_equal SY::Length
198
+ SY::Length.standard_unit.must_equal SY::METRE
199
+ SY::METRE.amount.must_equal 1
200
+ SY::METRE.mili.amount.must_equal 0.001
201
+ 3.km.in( :dm ).must_equal 30_000
202
+ ( 1.m + 20.cm ).must_equal 1_200.mm
203
+ assert 1.mm.object_id != 1.mm.object_id
204
+ assert 1.mm == 1.mm
205
+ assert 1.01.m != 1.m
206
+ assert_equal 1, 1.01.m <=> 1.m
207
+ assert_equal 0, 1.00.m <=> 1.m
208
+ assert_equal -1, 0.99.m <=> 1.m
209
+ assert 0.9.mm < 1.mm
210
+ assert 1.1.mm > 1.09.mm
211
+ assert ( 0.1.m - ( 1.m - 0.9.m ) ).abs < 1.nm.abs
212
+ # Mass quantity and typical units
213
+ SY::KILOGRAM.must_be_kind_of SY::Unit
214
+ SY::GRAM.must_be_kind_of SY::Unit
215
+ assert SY::Mass.standard_unit.equal?( SY::KILOGRAM )
216
+ 1.kilogram.must_be_kind_of SY::Magnitude
217
+ 1.gram.must_be_kind_of SY::Magnitude
218
+ 1.kilogram.absolute.quantity.must_equal SY::Mass
219
+ 1.gram.absolute.quantity.must_equal SY::Mass
220
+ ( SY::KILOGRAM * 1 ).must_equal SY::GRAM * 1000
221
+ 1.kilogram.must_equal 1000.g
222
+ 1.kg.to_f.must_equal 1
223
+ 1.g.to_f.must_equal 0.001
224
+ 1.miligram.must_equal 0.001.g
225
+ 1.mg.must_equal 1.miligram
226
+ 1.µg.must_equal 0.001.miligram
227
+ 1.ng.must_equal 0.001.microgram
228
+ 1.pg.quantity.must_equal 0.001.nanogram.quantity
229
+ 1.pg.amount.must_be_within_epsilon 0.001.nanogram.amount, 1e-6
230
+ assert_equal 1.g, [1.g, 2.g].min
231
+ assert_equal 1.mg, 1.g * 0.001
232
+ 1.pg.abs.must_be_within_epsilon 0.001.nanogram.abs, 1e-6
233
+ SY::TON.must_be_kind_of SY::Unit
234
+ 1.ton.must_equal 1000.kg
235
+ 1.t.must_equal 1.ton
236
+ 1.kt.must_equal 1000.ton
237
+ 1.Mt.must_equal 1000.kiloton
238
+ 1.mm.quantity.name.must_equal :Length±
239
+ SY::Length.standard_unit.must_equal SY::METRE
240
+ SY::Length.standard_unit.name.must_equal :metre
241
+ SY::Length.standard_unit.must_equal SY::METRE
242
+ SY.Quantity( :Length ).object_id.must_equal SY::Length.object_id
243
+ SY::Length.relative.object_id.must_equal SY.Quantity( :Length± ).object_id
244
+ SY.Quantity( :Length± ).colleague.name.must_equal :Length
245
+ SY.Quantity( :Length± ).colleague.class.must_equal SY::Quantity
246
+ SY.Quantity( :Length± ).colleague.object_id.must_equal SY::Length.object_id
247
+ SY.Quantity( :Length± ).send( :Unit ).object_id
248
+ .must_equal SY::Length.send( :Unit ).object_id
249
+ 1.mm.quantity.standard_unit.name.must_equal :metre
250
+ 1.mm.to_s.must_equal "0.001.m"
251
+ 1.mm.inspect.must_equal "#<±Magnitude: 0.001.m >"
252
+ 1.µs.inspect.must_equal "#<±Magnitude: 1e-06.s >"
253
+
254
+ SY::Area.dimension.must_equal SY.Dimension( :L² )
255
+ SY::Area.composition.must_equal SY::Composition[ SY::Length => 2 ]
256
+
257
+ SY::AMPERE.name.must_equal :ampere
258
+ SY::AMPERE.abbreviation.must_equal :A
259
+ SY::AMPERE.dimension.must_equal 1.A.dimension
260
+ SY.Magnitude( of: SY::ElectricCurrent, amount: 1 ).must_equal 1.A.absolute
261
+ 1.A.quantity.must_equal SY::ElectricCurrent.relative
262
+ 1.A.quantity.standard_unit.name.must_equal :ampere
263
+ 1.A.to_s( SY::AMPERE ).must_equal "1.A"
264
+ 1.A.to_s.must_equal "1.A"
265
+ 1.A.amount.must_equal 1
266
+ 1.A.quantity.standard_unit.abbreviation.must_equal :A
267
+ 1.A.inspect.must_equal "#<±Magnitude: 1.A >"
268
+
269
+ 1.l⁻¹.reframe( SY::Molarity ).quantity.must_equal SY::Molarity
270
+ x = ( SY::Nᴀ / SY::LITRE )
271
+ x = x.reframe( SY::Molarity )
272
+ y = 1.molar.absolute
273
+ y.quantity.must_equal x.quantity
274
+ y.amount.must_equal y.amount
275
+ SY::MoleAmount.protected?.must_equal true
276
+ SY::LitreVolume.protected?.must_equal true
277
+ SY::MOLAR.quantity.name.must_equal :Molarity
278
+ m = 1.µM
279
+ 1.µM.quantity.relative?.must_equal true
280
+ 1.µM.quantity.name.must_equal :Molarity±
281
+ 1.µM.quantity.absolute.name.must_equal :Molarity
282
+ 7.µM.must_be_within_epsilon 5.µM + 2.µM, 1e-6
283
+ +1.s.must_equal 1.s
284
+ # -1.s.must_equal -1 * 1.s # must raise
285
+ assert_equal -(-(1.s)), +(1.s)
286
+ 1.s⁻¹.quantity.must_equal ( 1.s ** -1 ).quantity
287
+ 1.s⁻¹.quantity.must_equal ( 1 / 1.s ).quantity
288
+ 1.s⁻¹.amount.must_equal ( 1.s ** -1 ).amount
289
+ 1.s⁻¹.must_equal 1.s ** -1
290
+ q1 = ( 1.s⁻¹ ).quantity
291
+ q1.composition.to_hash.must_equal( { SY::Time => -1 } )
292
+
293
+ q2 = ( 1 / 1.s ).quantity
294
+ q2.composition.to_hash.must_equal( { SY::Time => -1 } )
295
+
296
+ q1.relative?.must_equal true
297
+ q2.relative?.must_equal true
298
+
299
+ q1.object_id.must_equal q2.object_id
300
+ ( 1.s⁻¹ ).quantity.object_id.must_equal ( 1 / 1.s ).quantity.object_id
301
+ ( 1 / 1.s ).must_equal 1.s⁻¹
302
+ 1.s⁻¹.( SY::Frequency ).must_equal 1.Hz
303
+ # 7.°C.must_equal( 8.°C - 1.K )
304
+ # (-15).°C.must_equal 258.15.K
305
+ # 7000.µM.must_be_within_epsilon( 7.mM, 1e-9 )
306
+ ::SY::Unit.instances.map do |i|
307
+ begin
308
+ i.abbreviation
309
+ rescue
310
+ end
311
+ end.must_include :M
312
+ SY::Unit.instance_names.must_include :mole
313
+ # Avogadro's number is defined directly in SY
314
+ 1.mol.quantity.object_id.must_equal SY::Nᴀ.( SY::MoleAmount ).quantity.object_id
315
+ SY::Nᴀ.( SY::MoleAmount ).must_equal 1.mol
316
+ 0.7.mol.l⁻¹.amount.must_equal 0.7
317
+ 1.M.must_equal 1.mol.l⁻¹.( SY::Molarity )
318
+ # (if #reframe conversion method is not used, different quantities
319
+ # do not compare. Arithmetics is possible because Magnitude operators
320
+ # mostly give their results only in standard quantities.
321
+
322
+ # Avogadro's number is defined directly in SY
323
+ 1.mol.must_equal SY::Nᴀ.unit.( SY::MoleAmount )
324
+
325
+
326
+ 0.7.M.must_equal 0.7.mol.l⁻¹.( SY::Molarity )
327
+ # (if #is_actually! conversion method is not used, current
328
+ # implementation will refuse to compare different quantities,
329
+ # even if their dimensions match)
330
+
331
+ 30.Hz.must_equal 30.s⁻¹.( SY::Frequency )
332
+
333
+ # Dalton * Avogadro must be 1 gram
334
+ ( 1.Da * SY::Nᴀ ).must_be_within_epsilon( 1.g, 1e-6 )
335
+
336
+ # kilogram
337
+ 1.kg.must_equal 1000.g
338
+ SY::Speed.dimension.must_equal SY::Dimension( "L.T⁻¹" )
339
+ SY::Acceleration.dimension.must_equal SY::Dimension( "L.T⁻²" )
340
+ SY::Force.dimension.must_equal SY::Dimension( "L.M.T⁻²" )
341
+ ( 1.kg * 1.m.s⁻² ).( SY::Force ).must_be_within_epsilon 1.N, 1e-9
342
+
343
+ # joule
344
+ ( 1.N * 1.m ).( SY::Energy ).must_equal 1.J
345
+ 1e-23.J.K⁻¹.must_equal 1.0e-20.mJ.K⁻¹
346
+
347
+
348
+ # pascal
349
+ ( 1.N / 1.m ** 2 ).( SY::Pressure ).must_be_within_epsilon 1.Pa, 1e-9
350
+
351
+ # watt
352
+ ( 1.V * 1.A ).( SY::Power ).must_be_within_epsilon 1.W, 1e-9
353
+
354
+ # pretty representation
355
+ ( 1.m / 3.s ).to_s.must_equal( "0.333.m.s⁻¹" )
356
+ ( 1.m / 7.01e7.s ).to_s.must_equal( "1.43e-08.m.s⁻¹" )
357
+
358
+ assert_equal 1.m, 1.s * 1.m.s⁻¹
359
+ assert_equal 1.µM.s⁻¹, 1.µM / 1.s
360
+ assert_equal 1.m.s⁻¹, 1.m.s( -1 )
361
+ assert_equal 2_000.mm.s⁻², 2.m.s( -2 )
362
+ assert_equal 3.µM, 1.µM + 2.µM
363
+ assert_equal SY::Amount, SY::Molarity / SY::Molarity
364
+ assert_equal SY::Amount( 1 ), 1.µM / 1.µM
365
+ assert_equal SY::Amount( 1 ), 1.µM / ( 1.µM + 0.µM )
366
+ assert_equal 1.µM, 1.µM * 1.µM / ( 1.µM + 0.µM )
367
+ assert_in_epsilon 1.µM, 1.µmol / 1.dm( 3 ).( SY::LitreVolume )
368
+
369
+ assert_equal SY::Molarity.relative, 1.mol.l⁻¹.quantity
370
+
371
+ assert_equal 1 / SY::Time, 1 / SY::Time
372
+ assert_equal 1 / SY::Time.relative, 1 / SY::Time
373
+ assert_equal ( 1 / SY::Time.relative ), 1.mol.s⁻¹.( 1 / SY::Time ).quantity
374
+ assert_equal ( 1 / SY::Time ).object_id,
375
+ ( 1.0.µmol.min⁻¹.mg⁻¹ * 100.kDa ).( 1 / SY::Time ).quantity.object_id
376
+ assert_equal SY::Time.magnitude( 1 ), SY::SECOND
377
+ assert_equal Matrix[[60.mM], [60.mM]], Matrix[[1e-03.s⁻¹.M], [1e-3.s⁻¹.M]] * 60.s
378
+
379
+ assert_equal Matrix[[5.m]], Matrix[[1.m.s⁻¹, 2.m.s⁻¹]] * Matrix.column_vector( [1.s, 2.s] )
380
+ assert_equal Matrix[[2.m, 3.m], [4.m, 5.m]],
381
+ Matrix[[1.m, 2.m], [3.m, 4.m]] + Matrix[[1.m, 1.m], [1.m, 1.m]]
382
+ assert_equal Matrix[[5.µM]], Matrix[[1.µM]] + Matrix[[2.µM.s⁻¹]] * Matrix[[2.s]]
383
+ end
384
384
  end
385
385
  end