couchrest_model 2.1.0.rc1 → 2.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +15 -4
  4. data/Gemfile.activesupport-4.x +4 -0
  5. data/Gemfile.activesupport-5.x +4 -0
  6. data/README.md +2 -0
  7. data/VERSION +1 -1
  8. data/couchrest_model.gemspec +3 -2
  9. data/history.md +14 -1
  10. data/lib/couchrest/model/associations.rb +3 -8
  11. data/lib/couchrest/model/base.rb +15 -7
  12. data/lib/couchrest/model/casted_array.rb +22 -34
  13. data/lib/couchrest/model/configuration.rb +2 -0
  14. data/lib/couchrest/model/design.rb +4 -3
  15. data/lib/couchrest/model/designs/view.rb +37 -32
  16. data/lib/couchrest/model/dirty.rb +93 -19
  17. data/lib/couchrest/model/embeddable.rb +2 -14
  18. data/lib/couchrest/model/extended_attachments.rb +2 -4
  19. data/lib/couchrest/model/persistence.rb +14 -17
  20. data/lib/couchrest/model/properties.rb +46 -54
  21. data/lib/couchrest/model/property.rb +0 -3
  22. data/lib/couchrest/model/proxyable.rb +20 -4
  23. data/lib/couchrest/model/validations/uniqueness.rb +4 -1
  24. data/lib/couchrest_model.rb +2 -2
  25. data/spec/fixtures/models/article.rb +1 -1
  26. data/spec/fixtures/models/card.rb +2 -1
  27. data/spec/fixtures/models/person.rb +1 -0
  28. data/spec/fixtures/models/project.rb +3 -0
  29. data/spec/unit/assocations_spec.rb +73 -73
  30. data/spec/unit/attachment_spec.rb +34 -34
  31. data/spec/unit/base_spec.rb +102 -102
  32. data/spec/unit/casted_array_spec.rb +7 -7
  33. data/spec/unit/casted_spec.rb +7 -7
  34. data/spec/unit/configuration_spec.rb +11 -11
  35. data/spec/unit/connection_spec.rb +30 -30
  36. data/spec/unit/core_extensions/{time_parsing.rb → time_parsing_spec.rb} +21 -21
  37. data/spec/unit/design_spec.rb +38 -38
  38. data/spec/unit/designs/design_mapper_spec.rb +26 -26
  39. data/spec/unit/designs/migrations_spec.rb +13 -13
  40. data/spec/unit/designs/view_spec.rb +319 -274
  41. data/spec/unit/designs_spec.rb +39 -39
  42. data/spec/unit/dirty_spec.rb +188 -103
  43. data/spec/unit/embeddable_spec.rb +119 -117
  44. data/spec/unit/inherited_spec.rb +4 -4
  45. data/spec/unit/persistence_spec.rb +122 -122
  46. data/spec/unit/properties_spec.rb +466 -16
  47. data/spec/unit/property_protection_spec.rb +32 -32
  48. data/spec/unit/property_spec.rb +45 -436
  49. data/spec/unit/proxyable_spec.rb +140 -82
  50. data/spec/unit/subclass_spec.rb +14 -14
  51. data/spec/unit/translations_spec.rb +5 -5
  52. data/spec/unit/typecast_spec.rb +131 -131
  53. data/spec/unit/utils/migrate_spec.rb +2 -2
  54. data/spec/unit/validations_spec.rb +31 -31
  55. metadata +27 -12
  56. data/lib/couchrest/model/casted_hash.rb +0 -84
@@ -17,9 +17,9 @@ describe CouchRest::Model::CastedArray do
17
17
  prop = double('Property')
18
18
  parent = double('Parent')
19
19
  obj = klass.new([], prop, parent)
20
- obj.casted_by_property.should eql(prop)
21
- obj.casted_by.should eql(parent)
22
- obj.should be_empty
20
+ expect(obj.casted_by_property).to eql(prop)
21
+ expect(obj.casted_by).to eql(parent)
22
+ expect(obj).to be_empty
23
23
  end
24
24
  end
25
25
 
@@ -34,16 +34,16 @@ describe CouchRest::Model::CastedArray do
34
34
  ], property)
35
35
  end
36
36
  it "should return an array" do
37
- obj.as_couch_json.should be_a(Array)
37
+ expect(obj.as_couch_json).to be_a(Array)
38
38
  end
39
39
  it "should call as_couch_json on each value" do
40
- obj.first.should_receive(:as_couch_json)
40
+ expect(obj.first).to receive(:as_couch_json)
41
41
  obj.as_couch_json
42
42
  end
43
43
  it "should return value if no as_couch_json method" do
44
44
  obj = klass.new(['Felix', 'Garfield'], CouchRest::Model::Property.new(:title, :type => String))
45
- obj.first.should_not respond_to(:as_couch_json)
46
- obj.as_couch_json.first.should eql('Felix')
45
+ expect(obj.first).not_to respond_to(:as_couch_json)
46
+ expect(obj.as_couch_json.first).to eql('Felix')
47
47
  end
48
48
 
49
49
  end
@@ -23,11 +23,11 @@ describe "casting an extended document" do
23
23
  end
24
24
 
25
25
  it "should retain all properties of the casted attribute" do
26
- @car.driver.should == @driver
26
+ expect(@car.driver).to eq(@driver)
27
27
  end
28
28
 
29
29
  it "should let the casted document know who casted it" do
30
- @car.driver.casted_by.should == @car
30
+ expect(@car.driver.casted_by).to eq(@car)
31
31
  end
32
32
  end
33
33
 
@@ -39,17 +39,17 @@ describe "assigning a value to casted attribute after initializing an object" do
39
39
  end
40
40
 
41
41
  it "should not create an empty casted object" do
42
- @car.driver.should be_nil
42
+ expect(@car.driver).to be_nil
43
43
  end
44
44
 
45
45
  it "should let you assign the value" do
46
46
  @car.driver = @driver
47
- @car.driver.name.should == 'Matt'
47
+ expect(@car.driver.name).to eq('Matt')
48
48
  end
49
49
 
50
50
  it "should cast attribute" do
51
51
  @car.driver = JSON.parse(@driver.to_json)
52
- @car.driver.should be_instance_of(Driver)
52
+ expect(@car.driver).to be_instance_of(Driver)
53
53
  end
54
54
 
55
55
  end
@@ -63,10 +63,10 @@ describe "casting a model from parsed JSON" do
63
63
  end
64
64
 
65
65
  it "should cast casted attribute" do
66
- @new_car.driver.should be_instance_of(Driver)
66
+ expect(@new_car.driver).to be_instance_of(Driver)
67
67
  end
68
68
 
69
69
  it "should retain all properties of the casted attribute" do
70
- @new_car.driver.should == @driver
70
+ expect(@new_car.driver).to eq(@driver)
71
71
  end
72
72
  end
@@ -13,7 +13,7 @@ describe CouchRest::Model::Configuration do
13
13
  @class.configure do |config|
14
14
  config.foo_bar = 'monkey'
15
15
  end
16
- @class.foo_bar.should == 'monkey'
16
+ expect(@class.foo_bar).to eq('monkey')
17
17
  end
18
18
  end
19
19
 
@@ -22,7 +22,7 @@ describe CouchRest::Model::Configuration do
22
22
  it "should add a class level accessor" do
23
23
  @class.add_config :foo_bar
24
24
  @class.foo_bar = 'foo'
25
- @class.foo_bar.should == 'foo'
25
+ expect(@class.foo_bar).to eq('foo')
26
26
  end
27
27
 
28
28
  ['foo', :foo, 45, ['foo', :bar]].each do |val|
@@ -31,13 +31,13 @@ describe CouchRest::Model::Configuration do
31
31
  @child_class = Class.new(@class)
32
32
 
33
33
  @class.foo_bar = val
34
- @class.foo_bar.should == val
35
- @child_class.foo_bar.should == val
34
+ expect(@class.foo_bar).to eq(val)
35
+ expect(@child_class.foo_bar).to eq(val)
36
36
 
37
37
  @child_class.foo_bar = "bar"
38
- @child_class.foo_bar.should == "bar"
38
+ expect(@child_class.foo_bar).to eq("bar")
39
39
 
40
- @class.foo_bar.should == val
40
+ expect(@class.foo_bar).to eq(val)
41
41
  end
42
42
  end
43
43
 
@@ -45,13 +45,13 @@ describe CouchRest::Model::Configuration do
45
45
  it "should add an instance level accessor" do
46
46
  @class.add_config :foo_bar
47
47
  @class.foo_bar = 'foo'
48
- @class.new.foo_bar.should == 'foo'
48
+ expect(@class.new.foo_bar).to eq('foo')
49
49
  end
50
50
 
51
51
  it "should add a convenient in-class setter" do
52
52
  @class.add_config :foo_bar
53
53
  @class.foo_bar "monkey"
54
- @class.foo_bar.should == "monkey"
54
+ expect(@class.foo_bar).to eq("monkey")
55
55
  end
56
56
  end
57
57
 
@@ -67,10 +67,10 @@ describe CouchRest::Model::Configuration do
67
67
  Cat.instance_eval do
68
68
  model_type_key 'cat-type'
69
69
  end
70
- CouchRest::Model::Base.model_type_key.should eql(default_model_key)
71
- Cat.model_type_key.should eql('cat-type')
70
+ expect(CouchRest::Model::Base.model_type_key).to eql(default_model_key)
71
+ expect(Cat.model_type_key).to eql('cat-type')
72
72
  cat = Cat.new
73
- cat.model_type_key.should eql('cat-type')
73
+ expect(cat.model_type_key).to eql('cat-type')
74
74
  end
75
75
  end
76
76
 
@@ -14,20 +14,20 @@ describe CouchRest::Model::Connection do
14
14
 
15
15
  describe "#database" do
16
16
  it "should respond to" do
17
- @obj.should respond_to(:database)
17
+ expect(@obj).to respond_to(:database)
18
18
  end
19
19
  it "should provided class's database" do
20
- @obj.class.should_receive :database
20
+ expect(@obj.class).to receive :database
21
21
  @obj.database
22
22
  end
23
23
  end
24
24
 
25
25
  describe "#server" do
26
26
  it "should respond to method" do
27
- @obj.should respond_to(:server)
27
+ expect(@obj).to respond_to(:server)
28
28
  end
29
29
  it "should return class's server" do
30
- @obj.class.should_receive :server
30
+ expect(@obj.class).to receive :server
31
31
  @obj.server
32
32
  end
33
33
  end
@@ -36,13 +36,13 @@ describe CouchRest::Model::Connection do
36
36
  describe "default configuration" do
37
37
 
38
38
  it "should provide environment" do
39
- @class.environment.should eql(:development)
39
+ expect(@class.environment).to eql(:development)
40
40
  end
41
41
  it "should provide connection config file" do
42
- @class.connection_config_file.should eql(File.join(Dir.pwd, 'config', 'couchdb.yml'))
42
+ expect(@class.connection_config_file).to eql(File.join(Dir.pwd, 'config', 'couchdb.yml'))
43
43
  end
44
44
  it "should provided simple connection details" do
45
- @class.connection[:prefix].should eql('couchrest')
45
+ expect(@class.connection[:prefix]).to eql('couchrest')
46
46
  end
47
47
 
48
48
  end
@@ -51,46 +51,46 @@ describe CouchRest::Model::Connection do
51
51
 
52
52
  describe ".use_database" do
53
53
  it "should respond to" do
54
- @class.should respond_to(:use_database)
54
+ expect(@class).to respond_to(:use_database)
55
55
  end
56
56
  it "should set the database if object provided" do
57
57
  db = @class.server.database('test')
58
58
  @class.use_database(db)
59
- @class.database.should eql(db)
59
+ expect(@class.database).to eql(db)
60
60
  end
61
61
  it "should never prepare the database before it is needed" do
62
62
  db = @class.server.database('test')
63
- @class.should_not_receive(:prepare_database)
63
+ expect(@class).not_to receive(:prepare_database)
64
64
  @class.use_database('test')
65
65
  @class.use_database(db)
66
66
  end
67
67
  it "should use the database specified" do
68
68
  @class.use_database(:test)
69
- @class.database.name.should eql('couchrest_test')
69
+ expect(@class.database.name).to eql('couchrest_test')
70
70
  end
71
71
  end
72
72
 
73
73
  describe ".database" do
74
74
  it "should respond to" do
75
- @class.should respond_to(:database)
75
+ expect(@class).to respond_to(:database)
76
76
  end
77
77
  it "should provide a database object" do
78
- @class.database.should be_a(CouchRest::Database)
78
+ expect(@class.database).to be_a(CouchRest::Database)
79
79
  end
80
80
  it "should provide a database with default name" do
81
- @class.database.name.should eql('couchrest')
81
+ expect(@class.database.name).to eql('couchrest')
82
82
  end
83
83
  end
84
84
 
85
85
  describe ".server" do
86
86
  it "should respond to" do
87
- @class.should respond_to(:server)
87
+ expect(@class).to respond_to(:server)
88
88
  end
89
89
  it "should provide a server object" do
90
- @class.server.should be_a(CouchRest::Server)
90
+ expect(@class.server).to be_a(CouchRest::Server)
91
91
  end
92
92
  it "should provide a server with default config" do
93
- @class.server.uri.to_s.should eql("http://localhost:5984")
93
+ expect(@class.server.uri.to_s).to eql("http://localhost:5984")
94
94
  end
95
95
  it "should allow the configuration to be overwritten" do
96
96
  @class.connection = {
@@ -102,37 +102,37 @@ describe CouchRest::Model::Connection do
102
102
  :username => 'foo',
103
103
  :password => 'bar'
104
104
  }
105
- @class.server.uri.to_s.should eql("https://foo:bar@127.0.0.1:5985")
105
+ expect(@class.server.uri.to_s).to eql("https://foo:bar@127.0.0.1:5985")
106
106
  end
107
107
 
108
108
  it "should pass through the persistent connection option" do
109
109
  @class.connection[:persistent] = false
110
- expect(@class.server.connection_options[:persistent]).to be_false
110
+ expect(@class.server.connection_options[:persistent]).to be_falsey
111
111
  end
112
112
 
113
113
  end
114
114
 
115
115
  describe ".prepare_database" do
116
116
  it "should respond to" do
117
- @class.should respond_to(:prepare_database)
117
+ expect(@class).to respond_to(:prepare_database)
118
118
  end
119
119
 
120
120
  it "should join the database name correctly" do
121
121
  @class.connection[:suffix] = 'db'
122
122
  db = @class.prepare_database('test')
123
- db.name.should eql('couchrest_test_db')
123
+ expect(db.name).to eql('couchrest_test_db')
124
124
  end
125
125
 
126
126
  it "should ignore nil values in database name" do
127
127
  @class.connection[:suffix] = nil
128
128
  db = @class.prepare_database('test')
129
- db.name.should eql('couchrest_test')
129
+ expect(db.name).to eql('couchrest_test')
130
130
  end
131
131
 
132
132
  it "should use the .use_database value" do
133
133
  @class.use_database('testing')
134
134
  db = @class.prepare_database
135
- db.name.should eql('couchrest_testing')
135
+ expect(db.name).to eql('couchrest_testing')
136
136
  end
137
137
  end
138
138
 
@@ -140,26 +140,26 @@ describe CouchRest::Model::Connection do
140
140
 
141
141
  describe ".connection_configuration" do
142
142
  it "should provide main config by default" do
143
- @class.send(:connection_configuration).should eql(@class.connection)
143
+ expect(@class.send(:connection_configuration)).to eql(@class.connection)
144
144
  end
145
145
  it "should load file if available" do
146
146
  @class.connection_config_file = File.join(FIXTURE_PATH, 'config', 'couchdb.yml')
147
147
  hash = @class.send(:connection_configuration)
148
- hash[:protocol].should eql('https')
149
- hash[:host].should eql('sample.cloudant.com')
150
- hash[:join].should eql('_')
148
+ expect(hash[:protocol]).to eql('https')
149
+ expect(hash[:host]).to eql('sample.cloudant.com')
150
+ expect(hash[:join]).to eql('_')
151
151
  end
152
152
  end
153
153
 
154
154
  describe ".load_connection_config_file" do
155
155
  it "should provide an empty hash if config not found" do
156
- @class.send(:load_connection_config_file).should eql({})
156
+ expect(@class.send(:load_connection_config_file)).to eql({})
157
157
  end
158
158
  it "should load file if available" do
159
159
  @class.connection_config_file = File.join(FIXTURE_PATH, 'config', 'couchdb.yml')
160
160
  hash = @class.send(:load_connection_config_file)
161
- hash[:development].should_not be_nil
162
- @class.server.uri.to_s.should eql("https://test:user@sample.cloudant.com")
161
+ expect(hash[:development]).not_to be_nil
162
+ expect(@class.server.uri.to_s).to eql("https://test:user@sample.cloudant.com")
163
163
  end
164
164
 
165
165
  end
@@ -6,46 +6,46 @@ describe "Time Parsing core extension" do
6
6
  describe "Time" do
7
7
 
8
8
  it "should respond to .parse_iso8601" do
9
- Time.respond_to?("parse_iso8601").should be_true
9
+ expect(Time.respond_to?("parse_iso8601")).to be_truthy
10
10
  end
11
11
 
12
12
  describe "#as_json" do
13
13
 
14
14
  it "should convert local time to JSON string" do
15
15
  time = Time.new(2011, 04, 01, 19, 05, 30, "+02:00")
16
- time.as_json.should eql("2011-04-01T19:05:30.000+02:00")
16
+ expect(time.as_json).to eql("2011-04-01T19:05:30.000+02:00")
17
17
  end
18
18
 
19
19
  it "should convert utc time to JSON string" do
20
20
  time = Time.utc(2011, 04, 01, 19, 05, 30)
21
- time.as_json.should eql("2011-04-01T19:05:30.000Z")
21
+ expect(time.as_json).to eql("2011-04-01T19:05:30.000Z")
22
22
  end
23
23
 
24
24
  it "should convert local time with fraction to JSON" do
25
25
  time = Time.new(2011, 04, 01, 19, 05, 30.123, "+02:00")
26
- time.as_json.should eql("2011-04-01T19:05:30.123+02:00")
26
+ expect(time.as_json).to eql("2011-04-01T19:05:30.123+02:00")
27
27
  end
28
28
 
29
29
  it "should convert utc time with fraction to JSON" do
30
30
  time = Time.utc(2011, 04, 01, 19, 05, 30.123)
31
- time.as_json.should eql("2011-04-01T19:05:30.123Z")
31
+ expect(time.as_json).to eql("2011-04-01T19:05:30.123Z")
32
32
  end
33
33
 
34
34
  it "should allow fraction digits" do
35
35
  time = Time.utc(2011, 04, 01, 19, 05, 30.123456)
36
- time.as_json(:fraction_digits => 6).should eql("2011-04-01T19:05:30.123456Z")
36
+ expect(time.as_json(:fraction_digits => 6)).to eql("2011-04-01T19:05:30.123456Z")
37
37
  end
38
38
 
39
39
  it "should use CouchRest::Model::Base.time_fraction_digits config option" do
40
40
  CouchRest::Model::Base.time_fraction_digits = 6
41
41
  time = Time.utc(2011, 04, 01, 19, 05, 30.123456)
42
- time.as_json.should eql("2011-04-01T19:05:30.123456Z")
42
+ expect(time.as_json).to eql("2011-04-01T19:05:30.123456Z")
43
43
  CouchRest::Model::Base.time_fraction_digits = 3 # Back to normal
44
44
  end
45
45
 
46
46
  it "should cope with a nil options parameter" do
47
47
  time = Time.utc(2011, 04, 01, 19, 05, 30.123456)
48
- lambda { time.as_json(nil) }.should_not raise_error
48
+ expect { time.as_json(nil) }.not_to raise_error
49
49
  end
50
50
 
51
51
  end
@@ -56,69 +56,69 @@ describe "Time Parsing core extension" do
56
56
 
57
57
  before :each do
58
58
  # Time.parse should not be called for these tests!
59
- Time.stub!(:parse).and_return(nil)
59
+ allow(Time).to receive(:parse).and_return(nil)
60
60
  end
61
61
 
62
62
  it "should parse JSON time" do
63
63
  txt = "2011-04-01T19:05:30Z"
64
- Time.parse_iso8601(txt).should eql(Time.utc(2011, 04, 01, 19, 05, 30))
64
+ expect(Time.parse_iso8601(txt)).to eql(Time.utc(2011, 04, 01, 19, 05, 30))
65
65
  end
66
66
 
67
67
  it "should parse JSON time as UTC without Z" do
68
68
  txt = "2011-04-01T19:05:30"
69
- Time.parse_iso8601(txt).should eql(Time.utc(2011, 04, 01, 19, 05, 30))
69
+ expect(Time.parse_iso8601(txt)).to eql(Time.utc(2011, 04, 01, 19, 05, 30))
70
70
  end
71
71
 
72
72
  it "should parse basic time as UTC" do
73
73
  txt = "2011-04-01 19:05:30"
74
- Time.parse_iso8601(txt).should eql(Time.utc(2011, 04, 01, 19, 05, 30))
74
+ expect(Time.parse_iso8601(txt)).to eql(Time.utc(2011, 04, 01, 19, 05, 30))
75
75
  end
76
76
 
77
77
  it "should parse JSON time with zone" do
78
78
  txt = "2011-04-01T19:05:30 +02:00"
79
- Time.parse_iso8601(txt).should eql(Time.new(2011, 04, 01, 19, 05, 30, "+02:00"))
79
+ expect(Time.parse_iso8601(txt)).to eql(Time.new(2011, 04, 01, 19, 05, 30, "+02:00"))
80
80
  end
81
81
 
82
82
  it "should parse JSON time with zone 2" do
83
83
  txt = "2011-04-01T19:05:30-0200"
84
- Time.parse_iso8601(txt).should eql(Time.new(2011, 04, 01, 19, 05, 30, "-02:00"))
84
+ expect(Time.parse_iso8601(txt)).to eql(Time.new(2011, 04, 01, 19, 05, 30, "-02:00"))
85
85
  end
86
86
 
87
87
  it "should parse dodgy time with zone" do
88
88
  txt = "2011-04-01 19:05:30 +0200"
89
- Time.parse_iso8601(txt).should eql(Time.new(2011, 04, 01, 19, 05, 30, "+02:00"))
89
+ expect(Time.parse_iso8601(txt)).to eql(Time.new(2011, 04, 01, 19, 05, 30, "+02:00"))
90
90
  end
91
91
 
92
92
  it "should parse dodgy time with zone 2" do
93
93
  txt = "2011-04-01 19:05:30+0230"
94
- Time.parse_iso8601(txt).should eql(Time.new(2011, 04, 01, 19, 05, 30, "+02:30"))
94
+ expect(Time.parse_iso8601(txt)).to eql(Time.new(2011, 04, 01, 19, 05, 30, "+02:30"))
95
95
  end
96
96
 
97
97
  it "should parse dodgy time with zone 3" do
98
98
  txt = "2011-04-01 19:05:30 0230"
99
- Time.parse_iso8601(txt).should eql(Time.new(2011, 04, 01, 19, 05, 30, "+02:30"))
99
+ expect(Time.parse_iso8601(txt)).to eql(Time.new(2011, 04, 01, 19, 05, 30, "+02:30"))
100
100
  end
101
101
 
102
102
  it "should parse JSON time with second fractions" do
103
103
  txt = "2014-12-11T16:53:54.000Z"
104
- Time.parse_iso8601(txt).should eql(Time.utc(2014, 12, 11, 16, 53, Rational(54000, 1000)))
104
+ expect(Time.parse_iso8601(txt)).to eql(Time.utc(2014, 12, 11, 16, 53, Rational(54000, 1000)))
105
105
  end
106
106
 
107
107
  it "should avoid rounding errors parsing JSON time with second fractions" do
108
108
  txt = "2014-12-11T16:53:54.548Z"
109
- Time.parse_iso8601(txt).should eql(Time.utc(2014, 12, 11, 16, 53, Rational(54548,1000)))
109
+ expect(Time.parse_iso8601(txt)).to eql(Time.utc(2014, 12, 11, 16, 53, Rational(54548,1000)))
110
110
  end
111
111
 
112
112
  end
113
113
 
114
114
  it "avoids seconds rounding error" do
115
115
  time_string = "2014-12-11T16:54:54.549Z"
116
- Time.parse_iso8601(time_string).as_json.should eql(time_string)
116
+ expect(Time.parse_iso8601(time_string).as_json).to eql(time_string)
117
117
  end
118
118
 
119
119
  describe "resorting back to normal parse" do
120
120
  before :each do
121
- Time.should_receive(:parse)
121
+ expect(Time).to receive(:parse)
122
122
  end
123
123
  it "should work with weird time" do
124
124
  txt = "16/07/1981 05:04:00"