wagn 1.14.7 → 1.14.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/JASMINE_RAILS_TEST.md +16 -0
  3. data/VERSION +1 -1
  4. data/db/bootstrap/card_actions.yml +501 -480
  5. data/db/bootstrap/card_acts.yml +1 -1
  6. data/db/bootstrap/card_changes.yml +1815 -1752
  7. data/db/bootstrap/cards.yml +1500 -1443
  8. data/db/migrate/20141121172918_rename_card_migration_table.rb +8 -1
  9. data/lib/card/chunk.rb +0 -1
  10. data/lib/card/content.rb +1 -1
  11. data/lib/card/format.rb +6 -4
  12. data/lib/card/generators/card_migration/card_migration_generator.rb +1 -2
  13. data/lib/card/loader.rb +4 -0
  14. data/lib/card/set.rb +21 -7
  15. data/lib/card/set_pattern.rb +38 -5
  16. data/lib/wagn.rb +3 -3
  17. data/lib/wagn/core_migration.rb +1 -15
  18. data/lib/wagn/generators/wagn/templates/Rakefile +0 -1
  19. data/lib/wagn/log.rb +297 -94
  20. data/lib/wagn/migration.rb +53 -24
  21. data/lib/wagn/tasks/wagn.rake +17 -19
  22. data/mod/01_core/set/all/collection.rb +1 -1
  23. data/mod/01_core/set/all/content.rb +5 -2
  24. data/mod/01_core/set/all/fetch.rb +35 -35
  25. data/mod/01_core/set/all/trash.rb +3 -3
  26. data/mod/01_core/set/all/type.rb +7 -4
  27. data/mod/01_core/spec/set/all/tracked_attributes_spec.rb +1 -1
  28. data/mod/01_core/spec/set/all/trash_spec.rb +19 -0
  29. data/mod/02_basic_types/spec/set/type/pointer_spec.rb +13 -3
  30. data/mod/03_machines/set/type/coffee_script.rb +5 -3
  31. data/mod/03_machines/set/type/css.rb +4 -2
  32. data/mod/03_machines/set/type/java_script.rb +5 -4
  33. data/mod/04_settings/set/right/style.rb +3 -2
  34. data/mod/05_email/format/email_text_format.rb +4 -0
  35. data/mod/05_email/set/all/email_text.rb +1 -2
  36. data/mod/05_email/set/right/bcc.rb +8 -4
  37. data/mod/05_email/set/type/email_template.rb +20 -20
  38. data/mod/05_standard/set/all/attach.rb +0 -1
  39. data/mod/05_standard/set/type/basic.rb +3 -1
  40. data/mod/05_standard/set/type/html.rb +7 -5
  41. data/mod/05_standard/spec/set/type/email_template_spec.rb +166 -99
  42. data/public/assets/ace/ext-searchbox.js +409 -0
  43. data/spec/lib/card/set_pattern_spec.rb +18 -1
  44. data/spec/lib/wagn/log_spec.rb +217 -56
  45. data/test/fixtures/card_actions.yml +945 -924
  46. data/test/fixtures/card_acts.yml +101 -101
  47. data/test/fixtures/card_changes.yml +3764 -3701
  48. data/test/fixtures/cards.yml +2012 -1955
  49. metadata +4 -2
@@ -1,34 +1,59 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  class Wagn::Migration < ActiveRecord::Migration
4
- def self.find_unused_name base_name
5
- test_name = base_name
6
- add = 1
7
- while Card.exists?(test_name) do
8
- test_name = "#{base_name}#{add}"
9
- add +=1
4
+ @type = :deck_cards
5
+
6
+ class << self
7
+
8
+ # Rake tasks use class methods, migrations use instance methods.
9
+ # To avoid repetition a lot of instance methods here just call class methods.
10
+ # The subclass Wagn::CoreMigration needs a different @type so we can't use a
11
+ # class variable @@type. It has to be a class instance variable.
12
+ # Migrations are subclasses of Wagn::Migration or Wagn::CoreMigration but they
13
+ # don't inherit the @type. The method below solves this problem.
14
+ def type
15
+ @type || (ancestors[1] && ancestors[1].type)
16
+ end
17
+
18
+ def find_unused_name base_name
19
+ test_name = base_name
20
+ add = 1
21
+ while Card.exists?(test_name) do
22
+ test_name = "#{base_name}#{add}"
23
+ add +=1
24
+ end
25
+ test_name
10
26
  end
11
- test_name
12
- end
13
27
 
14
- def self.paths type
15
- Wagn.paths["db/migrate#{schema_suffix type}"].to_a
16
- end
28
+ def paths mig_type=type
29
+ Wagn.paths["db/migrate#{schema_suffix mig_type}"].to_a
30
+ end
17
31
 
18
- def self.schema_suffix type
19
- Wagn::Version.schema_suffix type
20
- end
32
+ def schema_suffix mig_type=type
33
+ Wagn::Version.schema_suffix( mig_type )
34
+ end
21
35
 
22
- def self.schema_mode type
23
- new_suffix = Wagn::Migration.schema_suffix type
24
- original_suffix = ActiveRecord::Base.table_name_suffix
36
+ def schema_mode mig_type=type
37
+ new_suffix = schema_suffix mig_type
38
+ original_suffix = ActiveRecord::Base.table_name_suffix
39
+
40
+ ActiveRecord::Base.table_name_suffix = new_suffix
41
+ yield
42
+ ActiveRecord::Base.table_name_suffix = original_suffix
43
+ end
25
44
 
26
- ActiveRecord::Base.table_name_suffix = new_suffix
27
- yield
28
- ActiveRecord::Base.table_name_suffix = original_suffix
29
- end
30
-
31
45
 
46
+ def data_path filename=nil
47
+ if filename
48
+ self.paths.each do |path|
49
+ path_to_file = File.join path, 'data', filename
50
+ return path_to_file if File.exists? path_to_file
51
+ end
52
+ else
53
+ File.join self.paths.first, 'data'
54
+ end
55
+ end
56
+ end
32
57
 
33
58
  def contentedly &block
34
59
  Wagn::Cache.reset_global
@@ -56,6 +81,7 @@ class Wagn::Migration < ActiveRecord::Migration
56
81
  end
57
82
  end
58
83
 
84
+
59
85
  def import_json filename
60
86
  Wagn.config.action_mailer.perform_deliveries = false
61
87
  raw_json = File.read( data_path filename )
@@ -63,13 +89,16 @@ class Wagn::Migration < ActiveRecord::Migration
63
89
  Card.merge_list json["card"]["value"], :output_file=>File.join(data_path,"unmerged_#{ filename }")
64
90
  end
65
91
 
92
+ def data_path filename=nil
93
+ self.class.data_path filename
94
+ end
66
95
 
67
96
  def schema_mode
68
- Wagn::Migration.schema_mode :deck_cards
97
+ self.class.schema_mode
69
98
  end
70
99
 
71
100
  def migration_paths
72
- Wagn::Migration.paths :deck_cards
101
+ self.class.paths
73
102
  end
74
103
 
75
104
 
@@ -1,6 +1,14 @@
1
1
 
2
2
  WAGN_BOOTSTRAP_TABLES = %w{ cards card_actions card_acts card_changes card_references }
3
3
 
4
+ def prepare_migration
5
+ Wagn::Cache.reset_global
6
+ Wagn.config.action_mailer.perform_deliveries = false
7
+ Card.reset_column_information
8
+ Card::Reference.reset_column_information # this is needed in production mode to insure core db
9
+ # structures are loaded before schema_mode is set
10
+ end
11
+
4
12
  namespace :wagn do
5
13
  desc "create a wagn database from scratch"
6
14
  task :create do
@@ -93,8 +101,8 @@ namespace :wagn do
93
101
 
94
102
  desc 'insert existing card migrations into schema_migrations_cards to avoid re-migrating'
95
103
  task :assume_card_migrations do
96
- Wagn::Migration.schema_mode :core_cards do
97
- ActiveRecord::Schema.assume_migrated_upto_version Wagn::Version.schema(:core_cards), Wagn::Migration.paths( :core_cards )
104
+ Wagn::CoreMigration.schema_mode do
105
+ ActiveRecord::Schema.assume_migrated_upto_version Wagn::Version.schema(:core_cards), Wagn::CoreMigration.paths
98
106
  end
99
107
  end
100
108
 
@@ -107,18 +115,11 @@ namespace :wagn do
107
115
 
108
116
  desc "migrate core cards"
109
117
  task :core_cards => :environment do
110
- Wagn::Cache.reset_global
111
118
  ENV['SCHEMA'] ||= "#{Wagn.gem_root}/db/schema.rb"
112
- Wagn.config.action_mailer.perform_deliveries = false
113
- Card.reset_column_information
114
- Card::Reference.reset_column_information
115
-
116
- # this is needed in production mode to insure core db structures are loaded before schema_mode is set
117
-
119
+ prepare_migration
120
+ paths = ActiveRecord::Migrator.migrations_paths = Wagn::CoreMigration.paths
118
121
 
119
- paths = ActiveRecord::Migrator.migrations_paths = Wagn::Migration.paths(:core_cards)
120
-
121
- Wagn::Migration.schema_mode :core_cards do
122
+ Wagn::CoreMigration.schema_mode do
122
123
  ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
123
124
  ActiveRecord::Migrator.migrate paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil
124
125
  end
@@ -126,15 +127,11 @@ namespace :wagn do
126
127
 
127
128
  desc "migrate deck cards"
128
129
  task :deck_cards => :environment do
129
- Wagn::Cache.reset_global
130
130
  ENV['SCHEMA'] ||= "#{Rails.root}/db/schema.rb"
131
- Wagn.config.action_mailer.perform_deliveries = false
132
- Card.reset_column_information # this is needed in production mode to insure core db structures are loaded before schema_mode is set
133
- Card::Reference.reset_column_information
131
+ prepare_migration
132
+ paths = ActiveRecord::Migrator.migrations_paths = Wagn::Migration.paths
134
133
 
135
- paths = ActiveRecord::Migrator.migrations_paths = Wagn::Migration.paths(:deck_cards)
136
-
137
- Wagn::Migration.schema_mode :deck_cards do
134
+ Wagn::Migration.schema_mode do
138
135
  ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
139
136
  ActiveRecord::Migrator.migrate paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil
140
137
  end
@@ -146,6 +143,7 @@ namespace :wagn do
146
143
  Wagn.config.action_mailer.perform_deliveries = false
147
144
 
148
145
  stamp_file = Wagn::Version.schema_stamp_path( args[:type] )
146
+
149
147
  Wagn::Migration.schema_mode args[:type] do
150
148
  version = ActiveRecord::Migrator.current_version
151
149
  if version.to_i > 0 and file = open(stamp_file, 'w')
@@ -2,7 +2,7 @@
2
2
  module ClassMethods
3
3
  def search spec
4
4
  query = ::Card::Query.new(spec)
5
- Wagn.with_logging :search, spec, :details=>query.sql.strip do
5
+ Wagn.with_logging :search, :message=>spec, :details=>query.sql.strip do
6
6
  results = query.run
7
7
  if block_given? and Array===results
8
8
  results.each { |result| yield result }
@@ -19,8 +19,11 @@ def raw_content
19
19
  structure ? template.db_content : db_content
20
20
  end
21
21
 
22
- def chunk_list #override to customize by set
23
- :default
22
+
23
+ format do
24
+ def chunk_list #override to customize by set
25
+ :default
26
+ end
24
27
  end
25
28
 
26
29
  def last_change_on(field, opts={})
@@ -19,49 +19,49 @@ module ClassMethods
19
19
  # :new => { card opts } Return a new card when not found
20
20
  #
21
21
 
22
+
23
+
22
24
 
23
25
  def fetch mark, opts={}
24
- Wagn.with_logging(:fetch, mark, :details=>opts) do
25
- if String === mark
26
- case mark
27
- when /^\~(\d+)$/ # get by id
28
- mark = $1.to_i
29
- when /^\:(\w+)$/ # get by codename
30
- mark = $1.to_sym
31
- end
26
+ if String === mark
27
+ case mark
28
+ when /^\~(\d+)$/ # get by id
29
+ mark = $1.to_i
30
+ when /^\:(\w+)$/ # get by codename
31
+ mark = $1.to_sym
32
32
  end
33
- mark = Card::Codename[mark] if Symbol === mark # id from codename
33
+ end
34
+ mark = Card::Codename[mark] if Symbol === mark # id from codename
34
35
 
35
- if mark.present?
36
- card, mark, needs_caching = fetch_from_cache_or_db mark, opts # have existing
37
- else
38
- return unless opts[:new]
39
- end
36
+ if mark.present?
37
+ card, mark, needs_caching = fetch_from_cache_or_db mark, opts # have existing
38
+ else
39
+ return unless opts[:new]
40
+ end
40
41
 
41
- if Integer===mark
42
- return if card.nil? || mark.nil?
42
+ if Integer===mark
43
+ return if card.nil? || mark.nil?
44
+ else
45
+ return card.renew(opts) if card and card.eager_renew?(opts)
46
+ if !card or card.type_id==-1 && clean_cache_opts?(opts) # new (or improved) card for cache
47
+ needs_caching = true
48
+ card = new_for_cache mark, opts
49
+ end
50
+ end
51
+
52
+ write_to_cache card if Card.cache && needs_caching
53
+
54
+ if card.new_card?
55
+ if opts[:new]
56
+ return card.renew(opts) if !clean_cache_opts? opts
43
57
  else
44
- return card.renew(opts) if card and card.eager_renew?(opts)
45
- if !card or card.type_id==-1 && clean_cache_opts?(opts) # new (or improved) card for cache
46
- needs_caching = true
47
- card = new_for_cache mark, opts
48
- end
49
- end
50
-
51
- write_to_cache card if Card.cache && needs_caching
52
-
53
- if card.new_card?
54
- if opts[:new]
55
- return card.renew(opts) if !clean_cache_opts? opts
56
- else
57
- return unless !opts[:skip_virtual] && card.virtual?
58
- end
59
- card.name = mark.to_s if mark && mark.to_s != card.name
58
+ return unless !opts[:skip_virtual] && card.virtual?
60
59
  end
61
-
62
- card.include_set_modules unless opts[:skip_modules]
63
- card
60
+ card.name = mark.to_s if mark && mark.to_s != card.name
64
61
  end
62
+
63
+ card.include_set_modules unless opts[:skip_modules]
64
+ card
65
65
  end
66
66
 
67
67
  def fetch_id mark #should optimize this. what if mark is int? or codename?
@@ -31,9 +31,9 @@ event :validate_delete, :before=>:approve, :on=>:delete do
31
31
  errors.add :delete, "#{name} is an indestructible rule"
32
32
  end
33
33
 
34
- # if account && Card::Revision.find_by_creator_id( self.id ) #ask ethan
35
- # errors.add :delete, "Edits have been made with #{name}'s user account.\n Deleting this card would mess up our revision records."
36
- # end
34
+ if account && Card::Act.find_by_actor_id( self.id )
35
+ errors.add :delete, "Edits have been made with #{name}'s user account.\nDeleting this card would mess up our history."
36
+ end
37
37
  end
38
38
 
39
39
  event :validate_delete_children, :after=>:approve, :on=>:delete do
@@ -6,7 +6,8 @@ module ClassMethods
6
6
  end
7
7
 
8
8
  def type_card
9
- Card[ type_id.to_i ]
9
+ return if type_id.nil?
10
+ Card.fetch type_id.to_i, :skip_modules=>true
10
11
  end
11
12
 
12
13
  def type_code
@@ -14,9 +15,11 @@ def type_code
14
15
  end
15
16
 
16
17
  def type_name
17
- return if type_id.nil?
18
- type_card = Card.fetch type_id.to_i, :skip_modules=>true, :skip_virtual=>true
19
- type_card and type_card.name
18
+ type_card.try :name
19
+ end
20
+
21
+ def type_cardname
22
+ type_card.try :cardname
20
23
  end
21
24
 
22
25
  def type= type_name
@@ -9,7 +9,7 @@ module RenameMethods
9
9
  #:revisions => card.actions.count,
10
10
  :referencers => card.referencers.map(&:name).sort,
11
11
  :referees => card.referees.map(&:name).sort,
12
- :dependents => card.dependents.map(&:id)
12
+ :dependents => card.dependents.map(&:id).sort
13
13
  }
14
14
  end
15
15
 
@@ -11,5 +11,24 @@ describe Card::Set::All::Trash do
11
11
  expect(Card[name]).to be
12
12
  end
13
13
  end
14
+
15
+ it 'does not delete account with edits' do
16
+ Card::Auth.as_bot do
17
+ name = 'Joe User'
18
+ card = Card[name]
19
+ card.delete
20
+ expect(card.errors[:delete].first).to match("Edits have been made with #{name}'s user account")
21
+ expect(Card[name]).to be
22
+ end
23
+ end
24
+
25
+ it 'deletes account without edits' do
26
+ Card::Auth.as_bot do
27
+ name = 'born to die'
28
+ card = Card.create! :name=>name, :type_code=>:user
29
+ card.delete
30
+ expect(Card[name]).not_to be
31
+ end
32
+ end
14
33
 
15
34
  end
@@ -48,25 +48,35 @@ describe Card::Set::Type::Pointer do
48
48
 
49
49
  describe "html" do
50
50
  before do
51
- Card::Auth.as_bot
52
- @card_name = "nonexistingcardmustnotexistthisistherule"
53
- @pointer = Card.create :name=>"tp", :type=>"pointer", :content=>"[[#{@card_name}]]"
51
+ Card::Auth.as_bot do
52
+ @card_name = "nonexistingcardmustnotexistthisistherule"
53
+ @pointer = Card.create :name=>"tp", :type=>"pointer", :content=>"[[#{@card_name}]]"
54
+ # similar tests for an inherited type of Pointer
55
+ @my_list = Card.create! :name=>'MyList', :type_id=>Card::CardtypeID
56
+ Card.create :name=>'MyList+*type+*default', :type_id=>Card::PointerID
57
+ @inherit_pointer = Card.create :name=>'ip', :type_id=>@my_list.id, :content=>"[[#{@card_name}]]"
58
+ end
54
59
  end
55
60
  it "should include nonexistingcardmustnotexistthisistherule in radio options" do
56
61
  option_html ="<input checked=\"checked\" class=\"pointer-radio-button\" id=\"pointer-radio-nonexistingcardmustnotexistthisistherule\" name=\"pointer_radio_button-tp\" type=\"radio\" value=\"nonexistingcardmustnotexistthisistherule\" />"
57
62
  @pointer.format.render_radio.should include(option_html)
63
+ option_html ="<input checked=\"checked\" class=\"pointer-radio-button\" id=\"pointer-radio-nonexistingcardmustnotexistthisistherule\" name=\"pointer_radio_button-ip\" type=\"radio\" value=\"nonexistingcardmustnotexistthisistherule\" />"
64
+ @inherit_pointer.format.render_radio.should include(option_html)
58
65
  end
59
66
  it "should include nonexistingcardmustnotexistthisistherule in checkbox options" do
60
67
  option_html = "<input checked=\"checked\" class=\"pointer-checkbox-button\" id=\"pointer-checkbox-nonexistingcardmustnotexistthisistherule\" name=\"pointer_checkbox\" type=\"checkbox\" value=\"nonexistingcardmustnotexistthisistherule\" />"
61
68
  @pointer.format.render_checkbox.should include(option_html)
69
+ @inherit_pointer.format.render_checkbox.should include(option_html)
62
70
  end
63
71
  it "should include nonexistingcardmustnotexistthisistherule in select options" do
64
72
  option_html = %{<option value="#{@card_name}" selected="selected">#{@card_name}</option>}
65
73
  @pointer.format.render_select.should include(option_html)
74
+ @inherit_pointer.format.render_select.should include(option_html)
66
75
  end
67
76
  it "should include nonexistingcardmustnotexistthisistherule in multiselect options" do
68
77
  option_html = %{<option value="#{@card_name}" selected="selected">#{@card_name}</option>}
69
78
  @pointer.format.render_multiselect.should include(option_html)
79
+ @inherit_pointer.format.render_multiselect.should include(option_html)
70
80
  end
71
81
  end
72
82
  describe "css" do
@@ -21,9 +21,11 @@ def clean_html?
21
21
  false
22
22
  end
23
23
 
24
- def chunk_list #turn off autodetection of uri's
25
- #TODO with the new format pattern this should be handled in the js format
26
- :inclusion_only
24
+
25
+ format do
26
+ def chunk_list #turn off autodetection of uri's
27
+ :inclusion_only
28
+ end
27
29
  end
28
30
 
29
31
 
@@ -21,8 +21,10 @@ def clean_html?
21
21
  false
22
22
  end
23
23
 
24
- def chunk_list #turn off autodetection of uri's
25
- :inclusion_and_link
24
+ format do
25
+ def chunk_list #turn off autodetection of uri's
26
+ :references
27
+ end
26
28
  end
27
29
 
28
30
 
@@ -15,13 +15,14 @@ def clean_html?
15
15
  false
16
16
  end
17
17
 
18
- def chunk_list #turn off autodetection of uri's
19
- #TODO with the new format pattern this should be handled in the js format
20
- :inclusion_only
18
+
19
+ format do
20
+ def chunk_list #turn off autodetection of uri's
21
+ :inclusion_only
22
+ end
21
23
  end
22
24
 
23
25
  format :html do
24
-
25
26
  view :editor, :mod=>PlainText::HtmlFormat
26
27
  view :content_changes, :mod=>CoffeeScript::HtmlFormat
27
28